-
Star
(544)
You must be signed in to star a gist -
Fork
(204)
You must be signed in to fork a gist
-
-
Save ryanflorence/701407 to your computer and use it in GitHub Desktop.
| var http = require("http"), | |
| url = require("url"), | |
| path = require("path"), | |
| fs = require("fs") | |
| port = process.argv[2] || 8888; | |
| http.createServer(function(request, response) { | |
| var uri = url.parse(request.url).pathname | |
| , filename = path.join(process.cwd(), uri); | |
| path.exists(filename, function(exists) { | |
| if(!exists) { | |
| response.writeHead(404, {"Content-Type": "text/plain"}); | |
| response.write("404 Not Found\n"); | |
| response.end(); | |
| return; | |
| } | |
| if (fs.statSync(filename).isDirectory()) filename += '/index.html'; | |
| fs.readFile(filename, "binary", function(err, file) { | |
| if(err) { | |
| response.writeHead(500, {"Content-Type": "text/plain"}); | |
| response.write(err + "\n"); | |
| response.end(); | |
| return; | |
| } | |
| response.writeHead(200); | |
| response.write(file, "binary"); | |
| response.end(); | |
| }); | |
| }); | |
| }).listen(parseInt(port, 10)); | |
| console.log("Static file server running at\n => http://localhost:" + port + "/\nCTRL + C to shutdown"); |
I'm 15 years late to the party, but this is indeed insecure. PoC:
curl --path-as-is http://localhost:8888/../../../../../../../../etc/passwd
By default, when you send HTTP requests using curl, they'll be normalized. With --path-as-is flag you can prevent normalization, thus the exploit works. The same thing happens if you test the PoC in your browser. I think that's why most people didn't find the vulnerability.
This is insecure, someone can request
/../../../etc/shadowor similar to read any file they want.I guess you're not familiar with how path.join works, because as coded here it won't resolve to a directory outside of cwd directory branch.
No, I think you're not familiar with how path.join works, there is no mitigation for the directory boundary check here. We wrote a paper about this vulnerability as it spread almost EVERYWHERE.
You can test it in Node:
node -e 'console.log(path.join("/opt/app/www", "/../../../../etc/passwd")) // It will print /etc/passwd'
Incredible article, thanks for sharing it! I think this article will also be useful for you - Node js vs Python.