-
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/shadow
or 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.