Files
codeql/javascript/ql/test/query-tests/Security/CWE-730/server-crash.js
2021-01-19 09:08:52 +01:00

167 lines
3.8 KiB
JavaScript

const express = require("express");
const app = express();
const fs = require("fs");
const EventEmitter = require("events");
const http = require("http");
const port = 12000;
let server = app.listen(port, () =>
// for manual testing of the fickle node.js runtime
console.log(`Example app listening on port ${port}!`)
);
function indirection1() {
fs.readFile("/foo", (err, x) => {
throw err; // NOT OK
});
}
function indirection2() {
throw 42; // NOT OK
}
function indirection3() {
try {
fs.readFile("/foo", (err, x) => {
throw err; // NOT OK
});
} catch (e) {}
}
function indirection4() {
throw 42; // OK: guarded caller
}
function indirection5() {
indirection6();
}
function indirection6() {
fs.readFile("/foo", (err, x) => {
throw err; // NOT OK
});
}
app.get("/async-throw", (req, res) => {
fs.readFile("/foo", (err, x) => {
throw err; // NOT OK
});
fs.readFile("/foo", (err, x) => {
try {
throw err; // OK: guarded throw
} catch (e) {}
});
fs.readFile("/foo", (err, x) => {
res.setHeader("reflected", req.query.header); // NOT OK [INCONSISTENCY]
});
fs.readFile("/foo", (err, x) => {
try {
res.setHeader("reflected", req.query.header); // OK: guarded call
} catch (e) {}
});
indirection1();
fs.readFile("/foo", (err, x) => {
indirection2();
});
indirection3();
try {
indirection4();
} catch (e) {}
indirection5();
fs.readFile("/foo", (err, x) => {
req.query.foo; // OK
});
fs.readFile("/foo", (err, x) => {
req.query.foo.toString(); // OK
});
fs.readFile("/foo", (err, x) => {
req.query.foo.bar; // NOT OK [INCONSISTENCY]: need to add property reads as sinks
});
fs.readFile("/foo", (err, x) => {
res.setHeader("reflected", unknown); // OK
});
try {
indirection7();
} catch (e) {}
});
function indirection7() {
fs.readFile("/foo", (err, x) => {
throw err; // NOT OK
});
}
app.get("/async-throw-again", (req, res) => {
fs.readFile("foo", () => {
throw "e"; // NOT OK
});
fs.readFileSync("foo", () => {
throw "e"; // OK (does not take callbacks at all)
});
// can nest async calls (and only warns about the inner one)
fs.readFile("foo", () => {
fs.readFile("bar", () => {
throw "e"; // NOT OK
});
});
fs.readFile("foo", () => {
// can not catch async exceptions
try {
fs.readFile("bar", () => {
throw "e"; // NOT OK
});
} catch (e) {}
});
// can mix sync/async calls
fs.readFile("foo", () => {
(() =>
fs.readFile("bar", () => {
throw "e"; // NOT OK
}))();
});
});
app.get("/throw-in-promise-1", async (req, res) => {
async function fun() {
throw new Error(); // OK, requires `node --unhandled-rejections=strict ...` to terminate the process
}
await fun();
});
app.get("/throw-in-promise-2", async (req, res) => {
async function fun() {
fs.readFile("/foo", (err, x) => {
throw err; // NOT OK
});
}
await fun();
});
app.get("/throw-in-promise-3", async (req, res) => {
fs.readFile("/foo", async (err, x) => {
throw err; // OK, requires `node --unhandled-rejections=strict ...` to terminate the process
});
});
app.get("/throw-in-event-emitter", async (req, res) => {
class MyEmitter extends EventEmitter {}
const myEmitter = new MyEmitter();
myEmitter.on("event", () => {
throw new Error(); // OK, requires `node --unhandled-rejections=strict ...` to terminate the process
});
myEmitter.emit("event");
});
app.get("/throw-with-ambiguous-paths", (req, res) => {
function throwError() {
throw new Error(); // NOT OK
}
function cb() {
throwError(); // on path
}
function withAsync() {
throwError(); // not on path
fs.stat(X, cb);
}
throwError(); // not on path
withAsync();
});