Add null byte injection mitigation to static web server tutorial
This commit is contained in:
parent
0bcac1f5b6
commit
a0e2645a0d
1 changed files with 60 additions and 1 deletions
|
@ -305,7 +305,7 @@ It's nearly finished! But encoded URLs will not work. To fix that, we will use `
|
|||
{% endcodeblock %}
|
||||
There is still one problem - the leak of "server.js" file. We can add a condition:
|
||||
{% codeblock server.js lang:javascript %}
|
||||
//Source code leakage mitigated
|
||||
//Source code leakage mitigated, but THERE IS A "%00" PROBLEM!
|
||||
var http = require("http");
|
||||
var fs = require("fs");
|
||||
var mime = require("mime-types");
|
||||
|
@ -362,6 +362,65 @@ There is still one problem - the leak of "server.js" file. We can add a conditio
|
|||
console.log("Started server at port " + port + ".");
|
||||
});
|
||||
{% endcodeblock %}
|
||||
Oh no! Our server may be vulnerable to null byte injection! You can remove null bytes and "%00", like this:
|
||||
{% codeblock server.js lang:javascript %}
|
||||
//Null byte injection mitigated!
|
||||
var http = require("http");
|
||||
var fs = require("fs");
|
||||
var mime = require("mime-types");
|
||||
var path = require("path");
|
||||
var os = require("os");
|
||||
var port = 8080;
|
||||
var server = http.createServer(function (req, res) {
|
||||
var urlObject = new URL(req.url, "http://localhost");
|
||||
var filename = "";
|
||||
try {
|
||||
filename = "." + decodeURIComponent(urlObject.pathname);
|
||||
} catch(ex) {
|
||||
//Malformed URI means bad request.
|
||||
res.writeHead(400, "Bad Request", {
|
||||
"Content-Type": "text/plain"
|
||||
});
|
||||
res.end("400 Bad Request");
|
||||
return;
|
||||
}
|
||||
filename = filename.replace(/\\/g,"/").replace(/\0|%00/g,"").replace(/\/\.\.?(?=\/|$)/g,"/").replace(/\/+/g,"/"); //Poor mans URL sanitizer
|
||||
if(filename == "./") filename = "./index.html";
|
||||
var ext = path.extname(filename).substr(1); //path.extname gives "." character, so we're using substr(1) method.
|
||||
if(filename == ("./" + path.basename(__filename)) || (os.platform() == "win32" && filename.toLowerCase() == ("./" + path.basename(__filename)).toLowerCase())) {
|
||||
//Prevent leakage of server source code
|
||||
res.writeHead(403, "Forbidden", {
|
||||
"Content-Type": "text/plain"
|
||||
});
|
||||
res.end("403 Forbidden");
|
||||
return;
|
||||
}
|
||||
fs.readFile(filename, function(err, data) {
|
||||
if(err) {
|
||||
if(err.code == "ENOENT") {
|
||||
//ENOENT means "File doesn't exist"
|
||||
res.writeHead(404, "Not Found", {
|
||||
"Content-Type": "text/plain"
|
||||
});
|
||||
res.end("404 Not Found");
|
||||
} else {
|
||||
res.writeHead(500, "Internal Server Error", {
|
||||
"Content-Type": "text/plain"
|
||||
});
|
||||
res.end("500 Internal Server Error! Reason: " + err.message);
|
||||
}
|
||||
} else {
|
||||
res.writeHead(200, "OK", {
|
||||
"Content-Type": mime.lookup(ext) || undefined
|
||||
});
|
||||
res.end(data);
|
||||
}
|
||||
});
|
||||
});
|
||||
server.listen(port, function() {
|
||||
console.log("Started server at port " + port + ".");
|
||||
});
|
||||
{% endcodeblock %}
|
||||
We have now very simple HTTP static server, serving at *localhost:8080*.
|
||||
|
||||
**Wait... Did we forget about [SVR.JS](https://svrjs.duckdns.org)?** SVR.JS is a web server running on Node.JS, that supports not only static file serving, but also directory listings, path rewriting, complete URL sanitation, HTTPS, HTTP/2.0, expandability via mods and server-side JavaScript, and it's configurable.
|
||||
|
|
Reference in a new issue