Add support for executing CGI outside cgi-bin directory

This commit is contained in:
Dorian Niemiec 2023-11-23 03:58:39 +01:00
parent d86d190f0b
commit b40e9ad55a

120
index.js
View file

@ -336,10 +336,37 @@ Mod.prototype.callback = function (req, res, serverconsole, responseEnd, href, e
} }
var isCgiBin = href.match(new RegExp("/cgi-bin(?:$|[?#/])", os.platform() == "win32" ? "i" : "")); var isCgiBin = href.match(new RegExp("/cgi-bin(?:$|[?#/])", os.platform() == "win32" ? "i" : ""));
if (isCgiBin) { var isScriptExt = scriptExts.indexOf(ext) != -1;
if ((href == "/redbrick-interpreters.json" || href == "/redbrick-scriptexts.json" || (os.platform() == "win32" && (href.toLowerCase() == "/redbrick-interpreters.json" || href.toLowerCase() == "/redbrick-scriptexts.json"))) && path.normalize(__dirname + "/../../..") == process.cwd()) {
if (!callServerError) {
res.writeHead(403, "Forbidden", {
"Content-Type": "text/html",
"Server": "RedBrick/" + version
});
res.write(
"<html><head><title>403 Forbidden</title></head><body><h1>403 Forbidden</h1><p>You don't have access to specific page.</p><p style=\"font-style: italic; font-weight: normal;\">SVR.JS " +
configJSON.version +
" (" +
os.platform()[0].toUpperCase() +
os.platform().slice(1) +
"; Node.JS/" +
process.version +
") RedBrick/" +
version +
" " +
(req.headers.host == undefined ? "" : " on " + req.headers.host) +
"</p></body></html>"
);
res.end(JSON.stringify(exttointerpreteruser, null, 2));
} else {
callServerError(403, "RedBrick/" + version);
}
} else {
fs.stat("." + href, function (err, stats) { fs.stat("." + href, function (err, stats) {
if (!err) { if (!err) {
if (!stats.isFile()) { if (!stats.isFile()) {
if(isCgiBin || scriptExts.indexOf(".php") != -1) {
fs.stat("." + href + "/index.php", function (e2, s2) { fs.stat("." + href + "/index.php", function (e2, s2) {
if (!e2 && s2.isFile()) { if (!e2 && s2.isFile()) {
try { try {
@ -389,7 +416,7 @@ Mod.prototype.callback = function (req, res, serverconsole, responseEnd, href, e
callServerError(500, "RedBrick/" + version, ex); callServerError(500, "RedBrick/" + version, ex);
} }
} }
} else { } else if(isCgiBin || scriptExts.indexOf(".cgi") != -1) {
fs.stat("." + href + "/index.cgi", function (e3, s3) { fs.stat("." + href + "/index.cgi", function (e3, s3) {
if (!e3 && s3.isFile()) { if (!e3 && s3.isFile()) {
try { try {
@ -443,9 +470,69 @@ Mod.prototype.callback = function (req, res, serverconsole, responseEnd, href, e
elseCallback(); elseCallback();
} }
}); });
} else {
elseCallback();
}
});
} else if(scriptExts.indexOf(".cgi") != -1) {
fs.stat("." + href + "/index.cgi", function (e3, s3) {
if (!e3 && s3.isFile()) {
try {
executeCGIWithEnv(
(href + "/index.cgi").replace(/\/+/g, "/"),
"",
req,
res,
req.socket.localAddress,
req.socket.localPort,
getCustomHeaders ?
getCustomHeaders()["Server"] +
" RedBrick/" +
version :
"SVR.JS/" +
configJSON.version +
" (" +
os.platform()[0].toUpperCase() +
os.platform().slice(1) +
"; Node.JS/" +
process.version +
") RedBrick/" +
version,
bheaders
);
} catch (ex) {
if (!callServerError) {
res.writeHead(500, "Internal Server Error", abheaders);
res.write(
"<html><head><title>500 Internal Server Error</title></head><body><h1>500 Internal Server Error</h1><p>A server had unexpected exception. Below, the stack trace of the error is shown:</p><code>" +
ex.stack.replace(/\r\n/g, "<br/>").replace(/\n/g, "<br/>").replace(/\r/g, "<br/>").replace(/ /g, "&nbsp;") +
"</code><p>Please contact the developer/administrator of the website.</p><p style=\"font-style: italic; font-weight: normal;\">SVR.JS " +
configJSON.version +
" (" +
os.platform()[0].toUpperCase() +
os.platform().slice(1) +
"; Node.JS/" +
process.version +
") RedBrick/" +
version +
" " +
(req.headers.host == undefined ? "" : " on " + req.headers.host) +
"</p></body></html>"
);
res.end();
} else {
callServerError(500, "RedBrick/" + version, ex);
}
}
} else {
elseCallback();
} }
}); });
} else { } else {
elseCallback();
}
} else {
if(isCgiBin || isScriptExt) {
try { try {
executeCGIWithEnv( executeCGIWithEnv(
href, href,
@ -493,6 +580,9 @@ Mod.prototype.callback = function (req, res, serverconsole, responseEnd, href, e
callServerError(500, "RedBrick/" + version, ex); callServerError(500, "RedBrick/" + version, ex);
} }
} }
} else {
elseCallback();
}
} }
} else if (err && err.code == "ENOTDIR") { } else if (err && err.code == "ENOTDIR") {
function checkPath(pth, cb, a) { function checkPath(pth, cb, a) {
@ -592,32 +682,6 @@ Mod.prototype.callback = function (req, res, serverconsole, responseEnd, href, e
elseCallback(); //Invoke default error handler elseCallback(); //Invoke default error handler
} }
}); });
} else if ((href == "/redbrick-interpreters.json" || href == "/redbrick-scriptexts.json" || (os.platform() == "win32" && (href.toLowerCase() == "/redbrick-interpreters.json" || href.toLowerCase() == "/redbrick-scriptexts.json"))) && path.normalize(__dirname + "/../../..") == process.cwd()) {
if (!callServerError) {
res.writeHead(403, "Forbidden", {
"Content-Type": "text/html",
"Server": "RedBrick/" + version
});
res.write(
"<html><head><title>403 Forbidden</title></head><body><h1>403 Forbidden</h1><p>You don't have access to specific page.</p><p style=\"font-style: italic; font-weight: normal;\">SVR.JS " +
configJSON.version +
" (" +
os.platform()[0].toUpperCase() +
os.platform().slice(1) +
"; Node.JS/" +
process.version +
") RedBrick/" +
version +
" " +
(req.headers.host == undefined ? "" : " on " + req.headers.host) +
"</p></body></html>"
);
res.end(JSON.stringify(exttointerpreteruser, null, 2));
} else {
callServerError(403, "RedBrick/" + version);
}
} else {
elseCallback();
} }
} }
} }