JS: Update OK-style comments to $-style

This commit is contained in:
Asger F
2025-02-06 13:34:01 +01:00
parent 7e5c24a8ec
commit 9be041e27d
536 changed files with 4408 additions and 4762 deletions

View File

@@ -44,7 +44,7 @@
/^https:\/\/[a-z]*.example.com$/; // $ Alert
RegExp('^protos?://(localhost|.+.example.net|.+.example-a.com|.+.example-b.com|.+.example.internal)'); // $ Alert
/^(example.dev|example.com)/; // OK
/^(example.dev|example.com)/;
new RegExp('^http://localhost:8000|' + '^https?://.+.example\\.com/'); // $ Alert
@@ -55,8 +55,8 @@
new RegExp('^http://test\.example.com'); // $ Alert
/^http:\/\/(..|...)\.example\.com\/index\.html/; // OK, wildcards are intentional
/^http:\/\/.\.example\.com\/index\.html/; // OK, the wildcard is intentional
/^http:\/\/(..|...)\.example\.com\/index\.html/; // OK - wildcards are intentional
/^http:\/\/.\.example\.com\/index\.html/; // OK - the wildcard is intentional
/^(foo.example\.com|whatever)$/; // $ Alert (but kinda OK - one disjunction doesn't even look like a hostname)
if (s.matchAll("^http://test.example.com")) {} // $ Alert

View File

@@ -41,7 +41,7 @@ function test5(url) {
function test6(url) {
let protocol = new URL(url).protocol;
if (badProtocolsGood.includes(protocol)) // OK
if (badProtocolsGood.includes(protocol))
return "about:blank";
return url;
}
@@ -113,7 +113,7 @@ function chain1(url) {
}
function chain2(url) {
return url // OK
return url
.replace(/javascript:/, "")
.replace(/data:/, "")
.replace(/vbscript:/, "");

View File

@@ -40,8 +40,8 @@
x.indexOf("index.php") !== -1;
x.indexOf("index.css") !== -1;
x.indexOf("secure=true") !== -1; // OK (query param)
x.indexOf("&auth=") !== -1; // OK (query param)
x.indexOf("secure=true") !== -1; // OK - query param
x.indexOf("&auth=") !== -1; // OK - query param
x.indexOf(getCurrentDomain()) !== -1; // $ MISSING: Alert
x.indexOf(location.origin) !== -1; // $ MISSING: Alert

View File

@@ -1,70 +1,70 @@
function endsWith(x, y) {
return x.indexOf(y) === x.length - y.length; // NOT OK
return x.indexOf(y) === x.length - y.length; // $ Alert
}
function endsWithGood(x, y) {
return x.length >= y.length && x.indexOf(y) === x.length - y.length; // OK
return x.length >= y.length && x.indexOf(y) === x.length - y.length;
}
function withStringConcat(x, y) {
return x.indexOf("/" + y) === x.length - y.length - 1; // NOT OK
return x.indexOf("/" + y) === x.length - y.length - 1; // $ Alert
}
function withStringConcatGood(x, y) {
return x.length > y.length && x.indexOf("/" + y) === x.length - y.length - 1; // OK
return x.length > y.length && x.indexOf("/" + y) === x.length - y.length - 1;
}
function withDelta(x, y) {
let delta = x.length - y.length;
return x.indexOf(y) === delta; // NOT OK
return x.indexOf(y) === delta; // $ Alert
}
function withDeltaGood(x, y) {
let delta = x.length - y.length;
return delta >= 0 && x.indexOf(y) === delta; // OK
return delta >= 0 && x.indexOf(y) === delta;
}
function literal(x) {
return x.indexOf("example.com") === x.length - "example.com".length; // NOT OK
return x.indexOf("example.com") === x.length - "example.com".length; // $ Alert
}
function literalGood(x) {
return x.length >= "example.com".length && x.indexOf("example.com") === x.length - "example.com".length;
}
function intLiteral(x) {
return x.indexOf("example.com") === x.length - 11; // NOT OK
return x.indexOf("example.com") === x.length - 11; // $ Alert
}
function intLiteralGood(x) {
return x.length >= 11 && x.indexOf("example.com") === x.length - 11;
}
function lastIndexOf(x, y) {
return x.lastIndexOf(y) === x.length - y.length; // NOT OK
return x.lastIndexOf(y) === x.length - y.length; // $ Alert
}
function lastIndexOfGood(x, y) {
return x.length >= y.length && x.lastIndexOf(y) === x.length - y.length; // OK
return x.length >= y.length && x.lastIndexOf(y) === x.length - y.length;
}
function withIndexOfCheckGood(x, y) {
let index = x.indexOf(y);
return index !== -1 && index === x.length - y.length - 1; // OK
return index !== -1 && index === x.length - y.length - 1;
}
function indexOfCheckEquality(x, y) {
return x.indexOf(y) !== -1 && x.indexOf(y) === x.length - y.length - 1; // OK
return x.indexOf(y) !== -1 && x.indexOf(y) === x.length - y.length - 1;
}
function indexOfCheckEqualityBad(x, y) {
return x.indexOf(y) !== 0 && x.indexOf(y) === x.length - y.length - 1; // NOT OK
return x.indexOf(y) !== 0 && x.indexOf(y) === x.length - y.length - 1; // $ Alert
}
function indexOfCheckGood(x, y) {
return x.indexOf(y) >= 0 && x.indexOf(y) === x.length - y.length - 1; // OK
return x.indexOf(y) >= 0 && x.indexOf(y) === x.length - y.length - 1;
}
function indexOfCheckGoodSharp(x, y) {
return x.indexOf(y) > -1 && x.indexOf(y) === x.length - y.length - 1; // OK
return x.indexOf(y) > -1 && x.indexOf(y) === x.length - y.length - 1;
}
function indexOfCheckBad(x, y) {
return x.indexOf(y) >= -1 && x.indexOf(y) === x.length - y.length - 1; // NOT OK
return x.indexOf(y) >= -1 && x.indexOf(y) === x.length - y.length - 1; // $ Alert
}
function endsWithSlash(x) {
@@ -73,39 +73,39 @@ function endsWithSlash(x) {
function withIndexOfCheckBad(x, y) {
let index = x.indexOf(y);
return index !== 0 && index === x.length - y.length - 1; // NOT OK
return index !== 0 && index === x.length - y.length - 1; // $ Alert
}
function plus(x, y) {
return x.indexOf("." + y) === x.length - (y.length + 1); // NOT OK
return x.indexOf("." + y) === x.length - (y.length + 1); // $ Alert
}
function withIndexOfCheckLower(x, y) {
let index = x.indexOf(y);
return !(index < 0) && index === x.length - y.length - 1; // OK
return !(index < 0) && index === x.length - y.length - 1;
}
function withIndexOfCheckLowerEq(x, y) {
let index = x.indexOf(y);
return !(index <= -1) && index === x.length - y.length - 1; // OK
return !(index <= -1) && index === x.length - y.length - 1;
}
function lastIndexNeqMinusOne(x) {
return x.lastIndexOf("example.com") !== -1 && x.lastIndexOf("example.com") === x.length - "example.com".length; // OK
return x.lastIndexOf("example.com") !== -1 && x.lastIndexOf("example.com") === x.length - "example.com".length;
}
function lastIndexEqMinusOne(x) {
return x.lastIndexOf("example.com") === -1 || x.lastIndexOf("example.com") === x.length - "example.com".length; // OK
return x.lastIndexOf("example.com") === -1 || x.lastIndexOf("example.com") === x.length - "example.com".length;
}
function sameCheck(allowedOrigin) {
const trustedAuthority = "example.com";
const ind = trustedAuthority.indexOf("." + allowedOrigin);
return ind > 0 && ind === trustedAuthority.length - allowedOrigin.length - 1; // OK
return ind > 0 && ind === trustedAuthority.length - allowedOrigin.length - 1;
}
function sameConcatenation(allowedOrigin) {
const trustedAuthority = "example.com";
return trustedAuthority.indexOf("." + allowedOrigin) > 0 && trustedAuthority.indexOf("." + allowedOrigin) === trustedAuthority.length - allowedOrigin.length - 1; // OK
return trustedAuthority.indexOf("." + allowedOrigin) > 0 && trustedAuthority.indexOf("." + allowedOrigin) === trustedAuthority.length - allowedOrigin.length - 1;
}

View File

@@ -8,7 +8,7 @@ window.onmessage = event => { // OK - good origin check
eval(event.data);
}
window.onmessage = event => { // NOT OK - no origin check
window.onmessage = event => { // $ Alert - no origin check
let origin = event.origin.toLowerCase();
console.log(origin);
@@ -21,7 +21,7 @@ window.onmessage = event => { // OK - there is an origin check
}
}
self.onmessage = function(e) { // NOT OK
self.onmessage = function(e) { // $ Alert
Commands[e.data.cmd].apply(null, e.data.args);
};
@@ -37,7 +37,7 @@ window.onmessage = event => { // OK - there is an origin check
}
}
self.onmessage = function(e) { // NOT OK
self.onmessage = function(e) { // $ Alert
Commands[e.data.cmd].apply(null, e.data.args);
};

View File

@@ -1,76 +1,76 @@
(function coreRegExp() {
/^a|/;
/^a|b/; // NOT OK
/^a|b/; // $ Alert
/a|^b/;
/^a|^b/;
/^a|b|c/; // NOT OK
/^a|b|c/; // $ Alert
/a|^b|c/;
/a|b|^c/;
/^a|^b|c/;
/(^a)|b/;
/^a|(b)/; // NOT OK
/^a|(b)/; // $ Alert
/^a|(^b)/;
/^(a)|(b)/; // NOT OK
/^(a)|(b)/; // $ Alert
/a|b$/; // NOT OK
/a|b$/; // $ Alert
/a$|b/;
/a$|b$/;
/a|b|c$/; // NOT OK
/a|b|c$/; // $ Alert
/a|b$|c/;
/a$|b|c/;
/a|b$|c$/;
/a|(b$)/;
/(a)|b$/; // NOT OK
/(a)|b$/; // $ Alert
/(a$)|b$/;
/(a)|(b)$/; // NOT OK
/(a)|(b)$/; // $ Alert
/^good.com|better.com/; // NOT OK
/^good\.com|better\.com/; // NOT OK
/^good\\.com|better\\.com/; // NOT OK
/^good\\\.com|better\\\.com/; // NOT OK
/^good\\\\.com|better\\\\.com/; // NOT OK
/^good.com|better.com/; // $ Alert
/^good\.com|better\.com/; // $ Alert
/^good\\.com|better\\.com/; // $ Alert
/^good\\\.com|better\\\.com/; // $ Alert
/^good\\\\.com|better\\\\.com/; // $ Alert
/^foo|bar|baz$/; // NOT OK
/^foo|%/; // OK
/^foo|bar|baz$/; // $ Alert
/^foo|%/;
});
(function coreString() {
new RegExp("^a|");
new RegExp("^a|b"); // NOT OK
new RegExp("^a|b"); // $ Alert
new RegExp("a|^b");
new RegExp("^a|^b");
new RegExp("^a|b|c"); // NOT OK
new RegExp("^a|b|c"); // $ Alert
new RegExp("a|^b|c");
new RegExp("a|b|^c");
new RegExp("^a|^b|c");
new RegExp("(^a)|b");
new RegExp("^a|(b)"); // NOT OK
new RegExp("^a|(b)"); // $ Alert
new RegExp("^a|(^b)");
new RegExp("^(a)|(b)"); // NOT OK
new RegExp("^(a)|(b)"); // $ Alert
new RegExp("a|b$"); // NOT OK
new RegExp("a|b$"); // $ Alert
new RegExp("a$|b");
new RegExp("a$|b$");
new RegExp("a|b|c$"); // NOT OK
new RegExp("a|b|c$"); // $ Alert
new RegExp("a|b$|c");
new RegExp("a$|b|c");
new RegExp("a|b$|c$");
new RegExp("a|(b$)");
new RegExp("(a)|b$"); // NOT OK
new RegExp("(a)|b$"); // $ Alert
new RegExp("(a$)|b$");
new RegExp("(a)|(b)$"); // NOT OK
new RegExp("(a)|(b)$"); // $ Alert
new RegExp('^good.com|better.com'); // NOT OK
new RegExp('^good\.com|better\.com'); // NOT OK
new RegExp('^good\\.com|better\\.com'); // NOT OK
new RegExp('^good\\\.com|better\\\.com'); // NOT OK
new RegExp('^good\\\\.com|better\\\\.com'); // NOT OK
new RegExp('^good.com|better.com'); // $ Alert
new RegExp('^good\.com|better\.com'); // $ Alert
new RegExp('^good\\.com|better\\.com'); // $ Alert
new RegExp('^good\\\.com|better\\\.com'); // $ Alert
new RegExp('^good\\\\.com|better\\\\.com'); // $ Alert
});
(function realWorld() {

View File

@@ -1,29 +1,29 @@
(function(x){
if ("http://evil.com/?http://good.com".match("https?://good.com")) {} // NOT OK
if ("http://evil.com/?http://good.com".match(new RegExp("https?://good.com"))) {} // NOT OK
if ("http://evil.com/?http://good.com".match("^https?://good.com")) {} // NOT OK - missing post-anchor
if ("http://evil.com/?http://good.com".match(/^https?:\/\/good.com/)) {} // NOT OK - missing post-anchor
if ("http://evil.com/?http://good.com".match("(^https?://good1.com)|(^https?://good2.com)")) {} // NOT OK - missing post-anchor
if ("http://evil.com/?http://good.com".match("(https?://good.com)|(^https?://goodie.com)")) {} // NOT OK - missing post-anchor
if ("http://evil.com/?http://good.com".match("https?://good.com")) {} // $ Alert
if ("http://evil.com/?http://good.com".match(new RegExp("https?://good.com"))) {} // $ Alert
if ("http://evil.com/?http://good.com".match("^https?://good.com")) {} // $ Alert - missing post-anchor
if ("http://evil.com/?http://good.com".match(/^https?:\/\/good.com/)) {} // $ Alert - missing post-anchor
if ("http://evil.com/?http://good.com".match("(^https?://good1.com)|(^https?://good2.com)")) {} // $ Alert - missing post-anchor
if ("http://evil.com/?http://good.com".match("(https?://good.com)|(^https?://goodie.com)")) {} // $ Alert - missing post-anchor
/https?:\/\/good.com/.exec("http://evil.com/?http://good.com"); // NOT OK
new RegExp("https?://good.com").exec("http://evil.com/?http://good.com"); // NOT OK
/https?:\/\/good.com/.exec("http://evil.com/?http://good.com"); // $ Alert
new RegExp("https?://good.com").exec("http://evil.com/?http://good.com"); // $ Alert
if ("http://evil.com/?http://good.com".search("https?://good.com") > -1) {} // NOT OK
if ("http://evil.com/?http://good.com".search("https?://good.com") > -1) {} // $ Alert
new RegExp("https?://good.com").test("http://evil.com/?http://good.com"); // NOT OK
new RegExp("https?://good.com").test("http://evil.com/?http://good.com"); // $ Alert
if ("something".match("other")) {} // OK
if ("something".match("x.commissary")) {} // OK
if ("http://evil.com/?http://good.com".match("https?://good.com")) {} // NOT OK
if ("http://evil.com/?http://good.com".match("https?://good.com:8080")) {} // NOT OK
if ("something".match("other")) {}
if ("something".match("x.commissary")) {}
if ("http://evil.com/?http://good.com".match("https?://good.com")) {} // $ Alert
if ("http://evil.com/?http://good.com".match("https?://good.com:8080")) {} // $ Alert
let trustedUrls = [
"https?://good.com", // NOT OK, referenced below
/https?:\/\/good.com/, // NOT OK, referenced below
new RegExp("https?://good.com"), // NOT OK, referenced below
"^https?://good.com" // NOT OK - missing post-anchor
"https?://good.com", // $ Alert - referenced below
/https?:\/\/good.com/, // $ Alert - referenced below
new RegExp("https?://good.com"), // $ Alert - referenced below
"^https?://good.com" // $ Alert - missing post-anchor
];
function isTrustedUrl(url) {
for (let trustedUrl of trustedUrls) {
@@ -32,10 +32,10 @@
return false;
}
/https?:\/\/good.com\/([0-9]+)/.exec(url); // NOT OK
"https://verygood.com/?id=" + /https?:\/\/good.com\/([0-9]+)/.exec(url)[0]; // OK
"http" + (secure? "s": "") + "://" + "verygood.com/?id=" + /https?:\/\/good.com\/([0-9]+)/.exec(url)[0]; // OK
"http" + (secure? "s": "") + "://" + ("verygood.com/?id=" + /https?:\/\/good.com\/([0-9]+)/.exec(url)[0]); // OK
/https?:\/\/good.com\/([0-9]+)/.exec(url); // $ Alert
"https://verygood.com/?id=" + /https?:\/\/good.com\/([0-9]+)/.exec(url)[0];
"http" + (secure? "s": "") + "://" + "verygood.com/?id=" + /https?:\/\/good.com\/([0-9]+)/.exec(url)[0];
"http" + (secure? "s": "") + "://" + ("verygood.com/?id=" + /https?:\/\/good.com\/([0-9]+)/.exec(url)[0]);
// g or .replace?
file = file.replace(
@@ -46,7 +46,7 @@
// missing context of use
const urlPatterns = [
{
regex: /youtube.com\/embed\/([a-z0-9\?&=\-_]+)/i, // OK
regex: /youtube.com\/embed\/([a-z0-9\?&=\-_]+)/i,
type: 'iframe', w: 560, h: 314,
url: '//www.youtube.com/embed/$1',
allowFullscreen: true
@@ -103,29 +103,29 @@
// replace
path.replace(/engine.io/, "$&-client");
/\.com|\.org/; // OK, has no domain name
/example\.com|whatever/; // OK, the other disjunction doesn't match a hostname
/\.com|\.org/; // OK - has no domain name
/example\.com|whatever/; // OK - the other disjunction doesn't match a hostname
// MatchAll test cases:
// Vulnerable patterns
if ("http://evil.com/?http://good.com".matchAll("https?://good.com")) {} // NOT OK
if ("http://evil.com/?http://good.com".matchAll(new RegExp("https?://good.com"))) {} // NOT OK
if ("http://evil.com/?http://good.com".matchAll("^https?://good.com")) {} // NOT OK - missing post-anchor
if ("http://evil.com/?http://good.com".matchAll(/^https?:\/\/good.com/g)) {} // NOT OK - missing post-anchor
if ("http://evil.com/?http://good.com".matchAll("(^https?://good1.com)|(^https?://good2.com)")) {} // NOT OK - missing post-anchor
if ("http://evil.com/?http://good.com".matchAll("(https?://good.com)|(^https?://goodie.com)")) {} // NOT OK - missing post-anchor
if ("http://evil.com/?http://good.com".matchAll("good.com")) {} // NOT OK - missing protocol
if ("http://evil.com/?http://good.com".matchAll("https?://good.com")) {} // NOT OK
if ("http://evil.com/?http://good.com".matchAll("https?://good.com:8080")) {} // NOT OK
if ("http://evil.com/?http://good.com".matchAll("https?://good.com")) {} // $ Alert
if ("http://evil.com/?http://good.com".matchAll(new RegExp("https?://good.com"))) {} // $ Alert
if ("http://evil.com/?http://good.com".matchAll("^https?://good.com")) {} // $ Alert - missing post-anchor
if ("http://evil.com/?http://good.com".matchAll(/^https?:\/\/good.com/g)) {} // $ Alert - missing post-anchor
if ("http://evil.com/?http://good.com".matchAll("(^https?://good1.com)|(^https?://good2.com)")) {} // $ Alert - missing post-anchor
if ("http://evil.com/?http://good.com".matchAll("(https?://good.com)|(^https?://goodie.com)")) {} // $ Alert - missing post-anchor
if ("http://evil.com/?http://good.com".matchAll("good.com")) {} // $ Alert - missing protocol
if ("http://evil.com/?http://good.com".matchAll("https?://good.com")) {} // $ Alert
if ("http://evil.com/?http://good.com".matchAll("https?://good.com:8080")) {} // $ Alert
// Non-vulnerable patterns
if ("something".matchAll("other")) {} // OK
if ("something".matchAll("x.commissary")) {} // OK
if ("http://evil.com/?http://good.com".matchAll("^https?://good.com$")) {} // OK
if ("http://evil.com/?http://good.com".matchAll(new RegExp("^https?://good.com$"))) {} // OK
if ("http://evil.com/?http://good.com".matchAll("^https?://good.com/$")) {} // OK
if ("http://evil.com/?http://good.com".matchAll(/^https?:\/\/good.com\/$/)) {} // OK
if ("http://evil.com/?http://good.com".matchAll("(^https?://good1.com$)|(^https?://good2.com$)")) {} // OK
if ("http://evil.com/?http://good.com".matchAll("(https?://good.com$)|(^https?://goodie.com$)")) {} // OK
if ("something".matchAll("other")) {}
if ("something".matchAll("x.commissary")) {}
if ("http://evil.com/?http://good.com".matchAll("^https?://good.com$")) {}
if ("http://evil.com/?http://good.com".matchAll(new RegExp("^https?://good.com$"))) {}
if ("http://evil.com/?http://good.com".matchAll("^https?://good.com/$")) {}
if ("http://evil.com/?http://good.com".matchAll(/^https?:\/\/good.com\/$/)) {}
if ("http://evil.com/?http://good.com".matchAll("(^https?://good1.com$)|(^https?://good2.com$)")) {}
if ("http://evil.com/?http://good.com".matchAll("(https?://good.com$)|(^https?://goodie.com$)")) {}
});

View File

@@ -1,34 +1,34 @@
var overlap1 = /^[0-93-5]$/; // NOT OK
var overlap1 = /^[0-93-5]$/; // $ Alert
var overlap2 = /[A-ZA-z]/; // NOT OK
var overlap2 = /[A-ZA-z]/; // $ Alert
var isEmpty = /^[z-a]$/; // NOT OK
var isEmpty = /^[z-a]$/; // $ Alert
var isAscii = /^[\x00-\x7F]*$/; // OK
var isAscii = /^[\x00-\x7F]*$/;
var printable = /[!-~]/; // OK - used to select most printable ASCII characters
var codePoints = /[^\x21-\x7E]|[[\](){}<>/%]/g; // OK
var codePoints = /[^\x21-\x7E]|[[\](){}<>/%]/g;
const NON_ALPHANUMERIC_REGEXP = /([^\#-~| |!])/g; // OK
const NON_ALPHANUMERIC_REGEXP = /([^\#-~| |!])/g;
var smallOverlap = /[0-9a-fA-f]/; // NOT OK
var smallOverlap = /[0-9a-fA-f]/; // $ Alert
var weirdRange = /[$-`]/; // NOT OK
var weirdRange = /[$-`]/; // $ Alert
var keywordOperator = /[!\~\*\/%+-<>\^|=&]/; // NOT OK
var keywordOperator = /[!\~\*\/%+-<>\^|=&]/; // $ Alert
var notYoutube = /youtu\.be\/[a-z1-9.-_]+/; // NOT OK
var notYoutube = /youtu\.be\/[a-z1-9.-_]+/; // $ Alert
var numberToLetter = /[7-F]/; // NOT OK
var numberToLetter = /[7-F]/; // $ Alert
var overlapsWithClass1 = /[0-9\d]/; // NOT OK
var overlapsWithClass1 = /[0-9\d]/; // $ Alert
var overlapsWithClass2 = /[\w,.-?:*+]/; // NOT OK
var overlapsWithClass2 = /[\w,.-?:*+]/; // $ Alert
var tst2 = /^([ァ-ヾ]|[ァ-ン゙゚])+$/; // OK
var tst3 = /[0-9-]/; // OK
var tst2 = /^([ァ-ヾ]|[ァ-ン゙゚])+$/;
var tst3 = /[0-9-]/;
var question = /[0-?]/; // OK. matches one of: 0123456789:;<=>?
var question = /[0-?]/; // OK - matches one of: 0123456789:;<=>?
var atToZ = /[@-Z]/; // OK. matches one of: @ABCDEFGHIJKLMNOPQRSTUVWXYZ
var atToZ = /[@-Z]/; // OK - matches one of: @ABCDEFGHIJKLMNOPQRSTUVWXYZ

View File

@@ -6,6 +6,5 @@ import { join } from 'path';
var server = createServer(function(req, res) {
let path = parse(req.url, true).query.path;
// BAD: This could read any file on the file system
res.write(readFileSync(join("public", path)));
res.write(readFileSync(join("public", path))); // $ Alert - This could read any file on the file system
});

View File

@@ -8,63 +8,52 @@ var fs = require('fs'),
var server = http.createServer(function(req, res) {
let path = url.parse(req.url, true).query.path;
// BAD: This could read any file on the file system
res.write(fs.readFileSync(path));
res.write(fs.readFileSync(path)); // $ Alert - This could read any file on the file system
// BAD: This could still read any file on the file system
res.write(fs.readFileSync("/home/user/" + path));
res.write(fs.readFileSync("/home/user/" + path)); // $ Alert - This could still read any file on the file system
if (path.startsWith("/home/user/"))
res.write(fs.readFileSync(path)); // BAD: Insufficient sanitisation
res.write(fs.readFileSync(path)); // $ Alert - Insufficient sanitisation
if (path.indexOf("secret") == -1)
res.write(fs.readFileSync(path)); // BAD: Insufficient sanitisation
res.write(fs.readFileSync(path)); // $ Alert - Insufficient sanitisation
if (fs.existsSync(path))
res.write(fs.readFileSync(path)); // BAD: Insufficient sanitisation
res.write(fs.readFileSync(path)); // $ Alert - Insufficient sanitisation
if (path === 'foo.txt')
res.write(fs.readFileSync(path)); // GOOD: Path is compared to white-list
res.write(fs.readFileSync(path)); // OK - Path is compared to white-list
if (path === 'foo.txt' || path === 'bar.txt')
res.write(fs.readFileSync(path)); // GOOD: Path is compared to white-list
res.write(fs.readFileSync(path)); // OK - Path is compared to white-list
if (path === 'foo.txt' || path === 'bar.txt' || someOpaqueCondition())
res.write(fs.readFileSync(path)); // BAD: Path is incompletely compared to white-list
res.write(fs.readFileSync(path)); // $ Alert - Path is incompletely compared to white-list
path = sanitize(path);
res.write(fs.readFileSync(path)); // GOOD: Path is sanitized
res.write(fs.readFileSync(path)); // OK - Path is sanitized
path = url.parse(req.url, true).query.path;
// GOOD: basename is safe
// OK - basename is safe
res.write(fs.readFileSync(pathModule.basename(path)));
// BAD: taint is preserved
res.write(fs.readFileSync(pathModule.dirname(path)));
// GOOD: extname is safe
res.write(fs.readFileSync(pathModule.dirname(path))); // $ Alert - taint is preserved
// OK - extname is safe
res.write(fs.readFileSync(pathModule.extname(path)));
// BAD: taint is preserved
res.write(fs.readFileSync(pathModule.join(path)));
// BAD: taint is preserved
res.write(fs.readFileSync(pathModule.join(x, y, path, z)));
// BAD: taint is preserved
res.write(fs.readFileSync(pathModule.normalize(path)));
// BAD: taint is preserved
res.write(fs.readFileSync(pathModule.relative(x, path)));
// BAD: taint is preserved
res.write(fs.readFileSync(pathModule.relative(path, x)));
// BAD: taint is preserved
res.write(fs.readFileSync(pathModule.resolve(path)));
// BAD: taint is preserved
res.write(fs.readFileSync(pathModule.resolve(x, y, path, z)));
// BAD: taint is preserved
res.write(fs.readFileSync(pathModule.toNamespacedPath(path)));
res.write(fs.readFileSync(pathModule.join(path))); // $ Alert - taint is preserved
res.write(fs.readFileSync(pathModule.join(x, y, path, z))); // $ Alert - taint is preserved
res.write(fs.readFileSync(pathModule.normalize(path))); // $ Alert - taint is preserved
res.write(fs.readFileSync(pathModule.relative(x, path))); // $ Alert - taint is preserved
res.write(fs.readFileSync(pathModule.relative(path, x))); // $ Alert - taint is preserved
res.write(fs.readFileSync(pathModule.resolve(path))); // $ Alert - taint is preserved
res.write(fs.readFileSync(pathModule.resolve(x, y, path, z))); // $ Alert - taint is preserved
res.write(fs.readFileSync(pathModule.toNamespacedPath(path))); // $ Alert - taint is preserved
});
var server = http.createServer(function(req, res) {
// tests for a few uri-libraries
res.write(fs.readFileSync(require("querystringify").parse(req.url).query)); // NOT OK
res.write(fs.readFileSync(require("query-string").parse(req.url).query)); // NOT OK
res.write(fs.readFileSync(require("querystring").parse(req.url).query)); // NOT OK
res.write(fs.readFileSync(require("querystringify").parse(req.url).query)); // $ Alert
res.write(fs.readFileSync(require("query-string").parse(req.url).query)); // $ Alert
res.write(fs.readFileSync(require("querystring").parse(req.url).query)); // $ Alert
});
(function(){
@@ -100,7 +89,7 @@ var server = http.createServer(function(req, res) {
path = path.replace(/\.\./g, ''); // remove all ".."
}
res.write(fs.readFileSync(path)); // OK. Is sanitized above.
res.write(fs.readFileSync(path)); // OK - Is sanitized above.
});
var server = http.createServer(function(req, res) {
@@ -113,36 +102,36 @@ var server = http.createServer(function(req, res) {
path = path.replace(/\.\./g, ''); // remove all ".."
}
res.write(fs.readFileSync(path)); // OK. Is sanitized above.
res.write(fs.readFileSync(path)); // OK - Is sanitized above.
});
var server = http.createServer(function(req, res) {
let path = url.parse(req.url, true).query.path;
require('send')(req, path); // NOT OK
require('send')(req, path); // $ Alert
});
var server = http.createServer(function(req, res) {
let path = url.parse(req.url, true).query.path;
fs.readFileSync(path); // NOT OK
fs.readFileSync(path); // $ Alert
var split = path.split("/");
fs.readFileSync(split.join("/")); // NOT OK
fs.readFileSync(split.join("/")); // $ Alert
fs.readFileSync(prefix + split[split.length - 1]) // OK
fs.readFileSync(prefix + split[split.length - 1])
fs.readFileSync(split[x]) // NOT OK
fs.readFileSync(prefix + split[x]) // NOT OK
fs.readFileSync(split[x]) // $ Alert
fs.readFileSync(prefix + split[x]) // $ Alert
var concatted = prefix.concat(split);
fs.readFileSync(concatted.join("/")); // NOT OK
fs.readFileSync(concatted.join("/")); // $ Alert
var concatted2 = split.concat(prefix);
fs.readFileSync(concatted2.join("/")); // NOT OK
fs.readFileSync(concatted2.join("/")); // $ Alert
fs.readFileSync(split.pop()); // NOT OK
fs.readFileSync(split.pop()); // $ Alert
});
@@ -150,33 +139,33 @@ var server = http.createServer(function(req, res) {
let path = url.parse(req.url, true).query.path;
// Removal of forward-slash or dots.
res.write(fs.readFileSync(path.replace(/[\]\[*,;'"`<>\\?\/]/g, ''))); // OK.
res.write(fs.readFileSync(path.replace(/[abcd]/g, ''))); // NOT OK
res.write(fs.readFileSync(path.replace(/[./]/g, ''))); // OK
res.write(fs.readFileSync(path.replace(/[foobar/foobar]/g, ''))); // OK
res.write(fs.readFileSync(path.replace(/\//g, ''))); // OK
res.write(fs.readFileSync(path.replace(/\.|\//g, ''))); // OK
res.write(fs.readFileSync(path.replace(/[\]\[*,;'"`<>\\?\/]/g, '')));
res.write(fs.readFileSync(path.replace(/[abcd]/g, ''))); // $ Alert
res.write(fs.readFileSync(path.replace(/[./]/g, '')));
res.write(fs.readFileSync(path.replace(/[foobar/foobar]/g, '')));
res.write(fs.readFileSync(path.replace(/\//g, '')));
res.write(fs.readFileSync(path.replace(/\.|\//g, '')));
res.write(fs.readFileSync(path.replace(/[.]/g, ''))); // NOT OK (can be absolute)
res.write(fs.readFileSync(path.replace(/[..]/g, ''))); // NOT OK (can be absolute)
res.write(fs.readFileSync(path.replace(/\./g, ''))); // NOT OK (can be absolute)
res.write(fs.readFileSync(path.replace(/\.\.|BLA/g, ''))); // NOT OK (can be absolute)
res.write(fs.readFileSync(path.replace(/[.]/g, ''))); // $ Alert - can be absolute
res.write(fs.readFileSync(path.replace(/[..]/g, ''))); // $ Alert - can be absolute
res.write(fs.readFileSync(path.replace(/\./g, ''))); // $ Alert - can be absolute
res.write(fs.readFileSync(path.replace(/\.\.|BLA/g, ''))); // $ Alert - can be absolute
if (!pathModule.isAbsolute(path)) {
res.write(fs.readFileSync(path.replace(/[.]/g, ''))); // OK
res.write(fs.readFileSync(path.replace(/[..]/g, ''))); // OK
res.write(fs.readFileSync(path.replace(/\./g, ''))); // OK
res.write(fs.readFileSync(path.replace(/\.\.|BLA/g, ''))); // OK
res.write(fs.readFileSync(path.replace(/[.]/g, '')));
res.write(fs.readFileSync(path.replace(/[..]/g, '')));
res.write(fs.readFileSync(path.replace(/\./g, '')));
res.write(fs.readFileSync(path.replace(/\.\.|BLA/g, '')));
}
// removing of "../" from prefix.
res.write(fs.readFileSync("prefix" + pathModule.normalize(path).replace(/^(\.\.[\/\\])+/, ''))); // OK
res.write(fs.readFileSync("prefix" + pathModule.normalize(path).replace(/(\.\.[\/\\])+/, ''))); // OK
res.write(fs.readFileSync("prefix" + pathModule.normalize(path).replace(/(\.\.\/)+/, ''))); // OK
res.write(fs.readFileSync("prefix" + pathModule.normalize(path).replace(/(\.\.\/)*/, ''))); // OK
res.write(fs.readFileSync("prefix" + pathModule.normalize(path).replace(/^(\.\.[\/\\])+/, '')));
res.write(fs.readFileSync("prefix" + pathModule.normalize(path).replace(/(\.\.[\/\\])+/, '')));
res.write(fs.readFileSync("prefix" + pathModule.normalize(path).replace(/(\.\.\/)+/, '')));
res.write(fs.readFileSync("prefix" + pathModule.normalize(path).replace(/(\.\.\/)*/, '')));
res.write(fs.readFileSync("prefix" + path.replace(/^(\.\.[\/\\])+/, ''))); // NOT OK - not normalized
res.write(fs.readFileSync(pathModule.normalize(path).replace(/^(\.\.[\/\\])+/, ''))); // NOT OK (can be absolute)
res.write(fs.readFileSync("prefix" + path.replace(/^(\.\.[\/\\])+/, ''))); // $ Alert - not normalized
res.write(fs.readFileSync(pathModule.normalize(path).replace(/^(\.\.[\/\\])+/, ''))); // $ Alert - can be absolute
});
import normalizeUrl from 'normalize-url';
@@ -184,38 +173,38 @@ import normalizeUrl from 'normalize-url';
var server = http.createServer(function(req, res) {
// tests for a few more uri-libraries
const qs = require("qs");
res.write(fs.readFileSync(qs.parse(req.url).foo)); // NOT OK
res.write(fs.readFileSync(qs.parse(normalizeUrl(req.url)).foo)); // NOT OK
res.write(fs.readFileSync(qs.parse(req.url).foo)); // $ Alert
res.write(fs.readFileSync(qs.parse(normalizeUrl(req.url)).foo)); // $ Alert
const parseqs = require("parseqs");
res.write(fs.readFileSync(parseqs.decode(req.url).foo)); // NOT OK
res.write(fs.readFileSync(parseqs.decode(req.url).foo)); // $ Alert
});
const cp = require("child_process");
var server = http.createServer(function(req, res) {
let path = url.parse(req.url, true).query.path;
cp.execSync("foobar", {cwd: path}); // NOT OK
cp.execFileSync("foobar", ["args"], {cwd: path}); // NOT OK
cp.execFileSync("foobar", {cwd: path}); // NOT OK
cp.execSync("foobar", {cwd: path}); // $ Alert
cp.execFileSync("foobar", ["args"], {cwd: path}); // $ Alert
cp.execFileSync("foobar", {cwd: path}); // $ Alert
});
var server = http.createServer(function(req, res) {
let path = url.parse(req.url, true).query.path;
// Removal of forward-slash or dots.
res.write(fs.readFileSync(path.replace(new RegExp("[\\]\\[*,;'\"`<>\\?/]", 'g'), ''))); // OK
res.write(fs.readFileSync(path.replace(new RegExp("[\\]\\[*,;'\"`<>\\?/]", ''), ''))); // NOT OK.
res.write(fs.readFileSync(path.replace(new RegExp("[\\]\\[*,;'\"`<>\\?/]", unknownFlags()), ''))); // OK -- Might be okay depending on what unknownFlags evaluates to.
res.write(fs.readFileSync(path.replace(new RegExp("[\\]\\[*,;'\"`<>\\?/]", 'g'), '')));
res.write(fs.readFileSync(path.replace(new RegExp("[\\]\\[*,;'\"`<>\\?/]", ''), ''))); // $ Alert
res.write(fs.readFileSync(path.replace(new RegExp("[\\]\\[*,;'\"`<>\\?/]", unknownFlags()), ''))); // OK - Might be okay depending on what unknownFlags evaluates to.
});
var server = http.createServer(function(req, res) {
let path = url.parse(req.url, true).query.path;
res.write(fs.readFileSync(path.replace(new RegExp("[.]", 'g'), ''))); // NOT OK (can be absolute)
res.write(fs.readFileSync(path.replace(new RegExp("[.]", 'g'), ''))); // $ Alert - can be absolute
if (!pathModule.isAbsolute(path)) {
res.write(fs.readFileSync(path.replace(new RegExp("[.]", ''), ''))); // NOT OK
res.write(fs.readFileSync(path.replace(new RegExp("[.]", 'g'), ''))); // OK
res.write(fs.readFileSync(path.replace(new RegExp("[.]", unknownFlags()), ''))); // OK
res.write(fs.readFileSync(path.replace(new RegExp("[.]", ''), ''))); // $ Alert
res.write(fs.readFileSync(path.replace(new RegExp("[.]", 'g'), '')));
res.write(fs.readFileSync(path.replace(new RegExp("[.]", unknownFlags()), '')));
}
});

View File

@@ -7,6 +7,5 @@ const ROOT = "/var/www/";
var server = http.createServer(function(req, res) {
let filePath = url.parse(req.url, true).query.path;
// BAD: This function uses unsanitized input that can read any file on the file system.
res.write(fs.readFileSync(ROOT + filePath, 'utf8'));
res.write(fs.readFileSync(ROOT + filePath, 'utf8')); // $ Alert - This function uses unsanitized input that can read any file on the file system.
});

View File

@@ -8,7 +8,7 @@ const ROOT = "/var/www/";
var server = http.createServer(function(req, res) {
let filePath = url.parse(req.url, true).query.path;
// GOOD: Verify that the file path is under the root directory
// OK - Verify that the file path is under the root directory
filePath = fs.realpathSync(path.resolve(ROOT, filePath));
if (!filePath.startsWith(ROOT)) {
res.statusCode = 403;

View File

@@ -26,27 +26,27 @@ function init() {
init();
app.get('/some/path1', function (req, res) {
res.send(data.compiledFileAccess({ path: req.params.path })); // NOT ALLOWED (template uses vulnerable catFile)
res.send(data.compiledFileAccess({ path: req.params.path })); // $ Alert - template uses vulnerable catFile
});
app.get('/some/path2', function (req, res) {
res.send(data.compiledBenign({ name: req.params.name })); // ALLOWED (this template does not use catFile)
res.send(data.compiledBenign({ name: req.params.name })); // OK - this template does not use catFile
});
app.get('/some/path3', function (req, res) {
res.send(data.compiledUnknown({ name: req.params.name })); // ALLOWED (could be using a vulnerable helper, but we'll assume it's ok)
res.send(data.compiledUnknown({ name: req.params.name })); // OK - could be using a vulnerable helper, but we'll assume it's ok
});
app.get('/some/path4', function (req, res) {
res.send(data.compiledMixed({
prefix: ">>> ",
path: req.params.path // NOT ALLOWED (template uses vulnerable helper)
path: req.params.path // $ Alert - template uses vulnerable helper
}));
});
app.get('/some/path5', function (req, res) {
res.send(data.compiledMixed({
prefix: req.params.prefix, // ALLOWED (this parameter is safe)
prefix: req.params.prefix, // OK - this parameter is safe
path: "data/path-5.txt"
}));
});

View File

@@ -10,21 +10,21 @@ let app = express();
app.get('/basic', (req, res) => {
let path = req.query.path;
fs.readFileSync(path); // NOT OK
fs.readFileSync('./' + path); // NOT OK
fs.readFileSync(path + '/index.html'); // NOT OK
fs.readFileSync(pathModule.join(path, 'index.html')); // NOT OK
fs.readFileSync(pathModule.join('/home/user/www', path)); // NOT OK
fs.readFileSync(path); // $ Alert
fs.readFileSync('./' + path); // $ Alert
fs.readFileSync(path + '/index.html'); // $ Alert
fs.readFileSync(pathModule.join(path, 'index.html')); // $ Alert
fs.readFileSync(pathModule.join('/home/user/www', path)); // $ Alert
});
app.get('/normalize', (req, res) => {
let path = pathModule.normalize(req.query.path);
fs.readFileSync(path); // NOT OK
fs.readFileSync('./' + path); // NOT OK
fs.readFileSync(path + '/index.html'); // NOT OK
fs.readFileSync(pathModule.join(path, 'index.html')); // NOT OK
fs.readFileSync(pathModule.join('/home/user/www', path)); // NOT OK
fs.readFileSync(path); // $ Alert
fs.readFileSync('./' + path); // $ Alert
fs.readFileSync(path + '/index.html'); // $ Alert
fs.readFileSync(pathModule.join(path, 'index.html')); // $ Alert
fs.readFileSync(pathModule.join('/home/user/www', path)); // $ Alert
});
app.get('/normalize-notAbsolute', (req, res) => {
@@ -33,21 +33,21 @@ app.get('/normalize-notAbsolute', (req, res) => {
if (pathModule.isAbsolute(path))
return;
fs.readFileSync(path); // NOT OK
fs.readFileSync(path); // $ Alert
if (!path.startsWith("."))
fs.readFileSync(path); // OK
fs.readFileSync(path);
else
fs.readFileSync(path); // NOT OK - wrong polarity
fs.readFileSync(path); // $ Alert - wrong polarity
if (!path.startsWith(".."))
fs.readFileSync(path); // OK
fs.readFileSync(path);
if (!path.startsWith("../"))
fs.readFileSync(path); // OK
fs.readFileSync(path);
if (!path.startsWith(".." + pathModule.sep))
fs.readFileSync(path); // OK
fs.readFileSync(path);
});
app.get('/normalize-noInitialDotDot', (req, res) => {
@@ -56,16 +56,16 @@ app.get('/normalize-noInitialDotDot', (req, res) => {
if (path.startsWith(".."))
return;
fs.readFileSync(path); // NOT OK - could be absolute
fs.readFileSync(path); // $ Alert - could be absolute
fs.readFileSync("./" + path); // OK - coerced to relative
fs.readFileSync(path + "/index.html"); // NOT OK - not coerced
fs.readFileSync(path + "/index.html"); // $ Alert - not coerced
if (!pathModule.isAbsolute(path))
fs.readFileSync(path); // OK
fs.readFileSync(path);
else
fs.readFileSync(path); // NOT OK
fs.readFileSync(path); // $ Alert
});
app.get('/prepend-normalize', (req, res) => {
@@ -73,9 +73,9 @@ app.get('/prepend-normalize', (req, res) => {
let path = pathModule.normalize('./' + req.query.path);
if (!path.startsWith(".."))
fs.readFileSync(path); // OK
fs.readFileSync(path);
else
fs.readFileSync(path); // NOT OK
fs.readFileSync(path); // $ Alert
});
app.get('/absolute', (req, res) => {
@@ -84,10 +84,10 @@ app.get('/absolute', (req, res) => {
if (!pathModule.isAbsolute(path))
return;
res.write(fs.readFileSync(path)); // NOT OK
res.write(fs.readFileSync(path)); // $ Alert
if (path.startsWith('/home/user/www'))
res.write(fs.readFileSync(path)); // NOT OK - can still contain '../'
res.write(fs.readFileSync(path)); // $ Alert - can still contain '../'
});
app.get('/normalized-absolute', (req, res) => {
@@ -96,10 +96,10 @@ app.get('/normalized-absolute', (req, res) => {
if (!pathModule.isAbsolute(path))
return;
res.write(fs.readFileSync(path)); // NOT OK
res.write(fs.readFileSync(path)); // $ Alert
if (path.startsWith('/home/user/www'))
res.write(fs.readFileSync(path)); // OK
res.write(fs.readFileSync(path));
});
app.get('/combined-check', (req, res) => {
@@ -107,53 +107,53 @@ app.get('/combined-check', (req, res) => {
// Combined absoluteness and folder check in one startsWith call
if (path.startsWith("/home/user/www"))
fs.readFileSync(path); // OK
fs.readFileSync(path);
if (path[0] !== "/" && path[0] !== ".")
fs.readFileSync(path); // OK
fs.readFileSync(path);
});
app.get('/realpath', (req, res) => {
let path = fs.realpathSync(req.query.path);
fs.readFileSync(path); // NOT OK
fs.readFileSync(pathModule.join(path, 'index.html')); // NOT OK
fs.readFileSync(path); // $ Alert
fs.readFileSync(pathModule.join(path, 'index.html')); // $ Alert
if (path.startsWith("/home/user/www"))
fs.readFileSync(path); // OK - both absolute and normalized before check
fs.readFileSync(pathModule.join('.', path)); // OK - normalized and coerced to relative
fs.readFileSync(pathModule.join('/home/user/www', path)); // OK
fs.readFileSync(pathModule.join('/home/user/www', path));
});
app.get('/coerce-relative', (req, res) => {
let path = pathModule.join('.', req.query.path);
if (!path.startsWith('..'))
fs.readFileSync(path); // OK
fs.readFileSync(path);
else
fs.readFileSync(path); // NOT OK
fs.readFileSync(path); // $ Alert
});
app.get('/coerce-absolute', (req, res) => {
let path = pathModule.join('/home/user/www', req.query.path);
if (path.startsWith('/home/user/www'))
fs.readFileSync(path); // OK
fs.readFileSync(path);
else
fs.readFileSync(path); // NOT OK
fs.readFileSync(path); // $ Alert
});
app.get('/concat-after-normalization', (req, res) => {
let path = 'foo/' + pathModule.normalize(req.query.path);
if (!path.startsWith('..'))
fs.readFileSync(path); // NOT OK - prefixing foo/ invalidates check
fs.readFileSync(path); // $ Alert - prefixing foo/ invalidates check
else
fs.readFileSync(path); // NOT OK
fs.readFileSync(path); // $ Alert
if (!path.includes('..'))
fs.readFileSync(path); // OK
fs.readFileSync(path);
});
app.get('/noDotDot', (req, res) => {
@@ -162,12 +162,12 @@ app.get('/noDotDot', (req, res) => {
if (path.includes('..'))
return;
fs.readFileSync(path); // NOT OK - can still be absolute
fs.readFileSync(path); // $ Alert - can still be absolute
if (!pathModule.isAbsolute(path))
fs.readFileSync(path); // OK
fs.readFileSync(path);
else
fs.readFileSync(path); // NOT OK
fs.readFileSync(path); // $ Alert
});
app.get('/join-regression', (req, res) => {
@@ -181,119 +181,119 @@ app.get('/join-regression', (req, res) => {
if (path.startsWith('/x')) {path;} else {path;}
if (path.startsWith('.')) {path;} else {path;}
fs.readFileSync(path); // NOT OK
fs.readFileSync(path); // $ Alert
if (pathModule.isAbsolute(path))
fs.readFileSync(path); // NOT OK
fs.readFileSync(path); // $ Alert
else
fs.readFileSync(path); // NOT OK
fs.readFileSync(path); // $ Alert
if (path.includes('..'))
fs.readFileSync(path); // NOT OK
fs.readFileSync(path); // $ Alert
else
fs.readFileSync(path); // NOT OK
fs.readFileSync(path); // $ Alert
if (!path.includes('..') && !pathModule.isAbsolute(path))
fs.readFileSync(path); // OK
fs.readFileSync(path);
else
fs.readFileSync(path); // NOT OK
fs.readFileSync(path); // $ Alert
let normalizedPath = pathModule.normalize(path);
if (normalizedPath.startsWith('/home/user/www'))
fs.readFileSync(normalizedPath); // OK
fs.readFileSync(normalizedPath);
else
fs.readFileSync(normalizedPath); // NOT OK
fs.readFileSync(normalizedPath); // $ Alert
if (normalizedPath.startsWith('/home/user/www') || normalizedPath.startsWith('/home/user/public'))
fs.readFileSync(normalizedPath); // OK - but flagged anyway [INCONSISTENCY]
fs.readFileSync(normalizedPath); // $ SPURIOUS: Alert
else
fs.readFileSync(normalizedPath); // NOT OK
fs.readFileSync(normalizedPath); // $ Alert
});
app.get('/decode-after-normalization', (req, res) => {
let path = pathModule.normalize(req.query.path);
if (!pathModule.isAbsolute(path) && !path.startsWith('..'))
fs.readFileSync(path); // OK
fs.readFileSync(path);
path = decodeURIComponent(path);
if (!pathModule.isAbsolute(path) && !path.startsWith('..'))
fs.readFileSync(path); // NOT OK - not normalized
fs.readFileSync(path); // $ Alert - not normalized
});
app.get('/replace', (req, res) => {
let path = pathModule.normalize(req.query.path).replace(/%20/g, ' ');
if (!pathModule.isAbsolute(path)) {
fs.readFileSync(path); // NOT OK
fs.readFileSync(path); // $ Alert
path = path.replace(/\.\./g, '');
fs.readFileSync(path); // OK
fs.readFileSync(path);
}
});
app.get('/resolve-path', (req, res) => {
let path = pathModule.resolve(req.query.path);
fs.readFileSync(path); // NOT OK
fs.readFileSync(path); // $ Alert
var self = something();
if (path.substring(0, self.dir.length) === self.dir)
fs.readFileSync(path); // OK
fs.readFileSync(path);
else
fs.readFileSync(path); // NOT OK - wrong polarity
fs.readFileSync(path); // $ Alert - wrong polarity
if (path.slice(0, self.dir.length) === self.dir)
fs.readFileSync(path); // OK
fs.readFileSync(path);
else
fs.readFileSync(path); // NOT OK - wrong polarity
fs.readFileSync(path); // $ Alert - wrong polarity
});
app.get('/relative-startswith', (req, res) => {
let path = pathModule.resolve(req.query.path);
fs.readFileSync(path); // NOT OK
fs.readFileSync(path); // $ Alert
var self = something();
var relative = pathModule.relative(self.webroot, path);
if(relative.startsWith(".." + pathModule.sep) || relative == "..") {
fs.readFileSync(path); // NOT OK!
fs.readFileSync(path); // $ Alert
} else {
fs.readFileSync(path); // OK!
fs.readFileSync(path);
}
let newpath = pathModule.normalize(path);
var relativePath = pathModule.relative(pathModule.normalize(workspaceDir), newpath);
if (relativePath.indexOf('..' + pathModule.sep) === 0) {
fs.readFileSync(newpath); // NOT OK!
fs.readFileSync(newpath); // $ Alert
} else {
fs.readFileSync(newpath); // OK!
fs.readFileSync(newpath);
}
let newpath = pathModule.normalize(path);
var relativePath = pathModule.relative(pathModule.normalize(workspaceDir), newpath);
if (relativePath.indexOf('../') === 0) {
fs.readFileSync(newpath); // NOT OK!
fs.readFileSync(newpath); // $ Alert
} else {
fs.readFileSync(newpath); // OK!
fs.readFileSync(newpath);
}
let newpath = pathModule.normalize(path);
var relativePath = pathModule.relative(pathModule.normalize(workspaceDir), newpath);
if (pathModule.normalize(relativePath).indexOf('../') === 0) {
fs.readFileSync(newpath); // NOT OK!
fs.readFileSync(newpath); // $ Alert
} else {
fs.readFileSync(newpath); // OK!
fs.readFileSync(newpath);
}
let newpath = pathModule.normalize(path);
var relativePath = pathModule.relative(pathModule.normalize(workspaceDir), newpath);
if (pathModule.normalize(relativePath).indexOf('../')) {
fs.readFileSync(newpath); // OK!
fs.readFileSync(newpath);
} else {
fs.readFileSync(newpath); // NOT OK!
fs.readFileSync(newpath); // $ Alert
}
});
@@ -301,35 +301,35 @@ var isPathInside = require("is-path-inside"),
pathIsInside = require("path-is-inside");
app.get('/pseudo-normalizations', (req, res) => {
let path = req.query.path;
fs.readFileSync(path); // NOT OK
fs.readFileSync(path); // $ Alert
if (isPathInside(path, SAFE)) {
fs.readFileSync(path); // OK
fs.readFileSync(path);
return;
} else {
fs.readFileSync(path); // NOT OK
fs.readFileSync(path); // $ Alert
}
if (pathIsInside(path, SAFE)) {
fs.readFileSync(path); // NOT OK - can be of the form 'safe/directory/../../../etc/passwd'
fs.readFileSync(path); // $ Alert - can be of the form 'safe/directory/../../../etc/passwd'
return;
} else {
fs.readFileSync(path); // NOT OK
fs.readFileSync(path); // $ Alert
}
let normalizedPath = pathModule.join(SAFE, path);
if (pathIsInside(normalizedPath, SAFE)) {
fs.readFileSync(normalizedPath); // OK
fs.readFileSync(normalizedPath);
return;
} else {
fs.readFileSync(normalizedPath); // NOT OK
fs.readFileSync(normalizedPath); // $ Alert
}
if (pathIsInside(normalizedPath, SAFE)) {
fs.readFileSync(normalizedPath); // OK
fs.readFileSync(normalizedPath);
return;
} else {
fs.readFileSync(normalizedPath); // NOT OK
fs.readFileSync(normalizedPath); // $ Alert
}
@@ -338,34 +338,34 @@ app.get('/pseudo-normalizations', (req, res) => {
app.get('/yet-another-prefix', (req, res) => {
let path = pathModule.resolve(req.query.path);
fs.readFileSync(path); // NOT OK
fs.readFileSync(path); // $ Alert
var abs = pathModule.resolve(path);
if (abs.indexOf(root) !== 0) {
fs.readFileSync(path); // NOT OK
fs.readFileSync(path); // $ Alert
return;
}
fs.readFileSync(path); // OK
fs.readFileSync(path);
});
var rootPath = process.cwd();
app.get('/yet-another-prefix2', (req, res) => {
let path = req.query.path;
fs.readFileSync(path); // NOT OK
fs.readFileSync(path); // $ Alert
var requestPath = pathModule.join(rootPath, path);
var targetPath;
if (!allowPath(requestPath, rootPath)) {
targetPath = rootPath;
fs.readFileSync(requestPath); // NOT OK
fs.readFileSync(requestPath); // $ Alert
} else {
targetPath = requestPath;
fs.readFileSync(requestPath); // OK
fs.readFileSync(requestPath);
}
fs.readFileSync(targetPath); // OK
fs.readFileSync(targetPath);
function allowPath(requestPath, rootPath) {
return requestPath.indexOf(rootPath) === 0;
@@ -376,56 +376,56 @@ import slash from 'slash';
app.get('/slash-stuff', (req, res) => {
let path = req.query.path;
fs.readFileSync(path); // NOT OK
fs.readFileSync(path); // $ Alert
fs.readFileSync(slash(path)); // NOT OK
fs.readFileSync(slash(path)); // $ Alert
});
app.get('/dotdot-regexp', (req, res) => {
let path = pathModule.normalize(req.query.x);
if (pathModule.isAbsolute(path))
return;
fs.readFileSync(path); // NOT OK
fs.readFileSync(path); // $ Alert
if (!path.match(/\./)) {
fs.readFileSync(path); // OK
fs.readFileSync(path);
}
if (!path.match(/\.\./)) {
fs.readFileSync(path); // OK
fs.readFileSync(path);
}
if (!path.match(/\.\.\//)) {
fs.readFileSync(path); // OK
fs.readFileSync(path);
}
if (!path.match(/\.\.\/foo/)) {
fs.readFileSync(path); // NOT OK
fs.readFileSync(path); // $ Alert
}
if (!path.match(/(\.\.\/|\.\.\\)/)) {
fs.readFileSync(path); // OK
fs.readFileSync(path);
}
});
app.get('/join-spread', (req, res) => {
fs.readFileSync(pathModule.join('foo', ...req.query.x.split('/'))); // NOT OK
fs.readFileSync(pathModule.join(...req.query.x.split('/'))); // NOT OK
fs.readFileSync(pathModule.join('foo', ...req.query.x.split('/'))); // $ Alert
fs.readFileSync(pathModule.join(...req.query.x.split('/'))); // $ Alert
});
app.get('/dotdot-matchAll-regexp', (req, res) => {
let path = pathModule.normalize(req.query.x);
if (pathModule.isAbsolute(path))
return;
fs.readFileSync(path); // NOT OK
fs.readFileSync(path); // $ Alert
if (!path.matchAll(/\./)) {
fs.readFileSync(path); // OK
fs.readFileSync(path);
}
if (!path.matchAll(/\.\./)) {
fs.readFileSync(path); // OK
fs.readFileSync(path);
}
if (!path.matchAll(/\.\.\//)) {
fs.readFileSync(path); // OK
fs.readFileSync(path);
}
if (!path.matchAll(/\.\.\/foo/)) {
fs.readFileSync(path); // NOT OK
fs.readFileSync(path); // $ Alert
}
if (!path.matchAll(/(\.\.\/|\.\.\\)/)) {
fs.readFileSync(path); // OK
fs.readFileSync(path);
}
});

View File

@@ -8,20 +8,20 @@ var http = require("http"),
var server = http.createServer(function(req, res) {
var path = url.parse(req.url, true).query.path;
fs.readFileSync(path); // NOT OK
gracefulFs.readFileSync(path); // NOT OK
fsExtra.readFileSync(path); // NOT OK
originalFs.readFileSync(path); // NOT OK
fs.readFileSync(path); // $ Alert
gracefulFs.readFileSync(path); // $ Alert
fsExtra.readFileSync(path); // $ Alert
originalFs.readFileSync(path); // $ Alert
getFsModule(true).readFileSync(path); // NOT OK
getFsModule(false).readFileSync(path); // NOT OK
getFsModule(true).readFileSync(path); // $ Alert
getFsModule(false).readFileSync(path); // $ Alert
require("./my-fs-module").require(true).readFileSync(path); // NOT OK
require("./my-fs-module").require(true).readFileSync(path); // $ Alert
let flexibleModuleName = require(process.versions["electron"]
? "original-fs"
: "fs");
flexibleModuleName.readFileSync(path); // NOT OK
flexibleModuleName.readFileSync(path); // $ Alert
});
function getFsModule(special) {
@@ -37,9 +37,9 @@ var util = require("util");
http.createServer(function(req, res) {
var path = url.parse(req.url, true).query.path;
util.promisify(fs.readFileSync)(path); // NOT OK
require("bluebird").promisify(fs.readFileSync)(path); // NOT OK
require("bluebird").promisifyAll(fs).readFileSync(path); // NOT OK
util.promisify(fs.readFileSync)(path); // $ Alert
require("bluebird").promisify(fs.readFileSync)(path); // $ Alert
require("bluebird").promisifyAll(fs).readFileSync(path); // $ Alert
});
@@ -48,37 +48,37 @@ const asyncFS = require("./my-async-fs-module");
http.createServer(function(req, res) {
var path = url.parse(req.url, true).query.path;
fs.readFileSync(path); // NOT OK
asyncFS.readFileSync(path); // NOT OK
fs.readFileSync(path); // $ Alert
asyncFS.readFileSync(path); // $ Alert
require("pify")(fs.readFileSync)(path); // NOT OK
require("pify")(fs).readFileSync(path); // NOT OK
require("pify")(fs.readFileSync)(path); // $ Alert
require("pify")(fs).readFileSync(path); // $ Alert
require('util.promisify')(fs.readFileSync)(path); // NOT OK
require('util.promisify')(fs.readFileSync)(path); // $ Alert
require("thenify")(fs.readFileSync)(path); // NOT OK
require("thenify")(fs.readFileSync)(path); // $ Alert
const readPkg = require('read-pkg');
var pkg = readPkg.readPackageSync({cwd: path}); // NOT OK
var pkgPromise = readPkg.readPackageAsync({cwd: path}); // NOT OK
var pkg = readPkg.readPackageSync({cwd: path}); // $ Alert
var pkgPromise = readPkg.readPackageAsync({cwd: path}); // $ Alert
});
const mkdirp = require("mkdirp");
http.createServer(function(req, res) {
var path = url.parse(req.url, true).query.path;
fs.readFileSync(path); // NOT OK
mkdirp(path); // NOT OK
mkdirp.sync(path); // NOT OK
fs.readFileSync(path); // $ Alert
mkdirp(path); // $ Alert
mkdirp.sync(path); // $ Alert
func(path);
});
function func(x) {
fs.readFileSync(x); // NOT OK
fs.readFileSync(x); // $ Alert
}
const fsp = require("fs/promises");
http.createServer(function(req, res) {
var path = url.parse(req.url, true).query.path;
fsp.readFile(path); // NOT OK
fsp.readFile(path); // $ Alert
});

View File

@@ -4,11 +4,11 @@ const prettier = require("prettier");
const app = express();
app.get('/some/path', function (req, res) {
const { p } = req.params;
prettier.resolveConfig(p).then((options) => { // NOT OK
prettier.resolveConfig(p).then((options) => { // $ Alert
const formatted = prettier.format("foo", options);
});
prettier.resolveConfig("foo", {config: p}).then((options) => { // NOT OK
prettier.resolveConfig("foo", {config: p}).then((options) => { // $ Alert
const formatted = prettier.format("bar", options);
});
});

View File

@@ -19,7 +19,7 @@ function getfileRoot(workspaceId) {
}
function withStatsAndETag(filepath, callback) {
fs.readFileSync(filepath); // NOT OK
fs.readFileSync(filepath); // $ Alert
};
function decodeUserIdFromWorkspaceId(workspaceId) {

View File

@@ -5,30 +5,30 @@ var fs = require('fs'),
var server = http.createServer(function(req, res) {
let path = url.parse(req.url, true).query.path;
fs.readFileSync(path); // NOT OK
fs.readFileSync(path); // $ Alert
var obj = bla ? something() : path;
fs.readFileSync(obj.sub); // NOT OK
fs.readFileSync(obj.sub); // $ Alert
obj.sub = "safe";
fs.readFileSync(obj.sub); // OK
fs.readFileSync(obj.sub);
obj.sub2 = "safe";
if (random()) {
fs.readFileSync(obj.sub2); // OK
fs.readFileSync(obj.sub2);
}
if (random()) {
obj.sub3 = "safe"
}
fs.readFileSync(obj.sub3); // NOT OK
fs.readFileSync(obj.sub3); // $ Alert
obj.sub4 =
fs.readFileSync(obj.sub4) ? // NOT OK
fs.readFileSync(obj.sub4) : // NOT OK
fs.readFileSync(obj.sub4); // NOT OK
fs.readFileSync(obj.sub4) ? // $ Alert
fs.readFileSync(obj.sub4) : // $ Alert
fs.readFileSync(obj.sub4); // $ Alert
});
server.listen();
@@ -37,7 +37,7 @@ var nodefs = require('node:fs');
var server2 = http.createServer(function(req, res) {
let path = url.parse(req.url, true).query.path;
nodefs.readFileSync(path); // NOT OK
nodefs.readFileSync(path); // $ Alert
});
server2.listen();
@@ -46,5 +46,5 @@ const chownr = require("chownr");
var server3 = http.createServer(function (req, res) {
let path = url.parse(req.url, true).query.path;
chownr(path, "someuid", "somegid", function (err) {}); // NOT OK
chownr(path, "someuid", "somegid", function (err) {}); // $ Alert
});

View File

@@ -7,11 +7,11 @@ var fs = require('fs'),
var server = http.createServer(function(req, res) {
let path = url.parse(req.url, true).query.path;
res.write(fs.readFileSync(['public', path].join('/'))); // BAD - but not flagged because we have no array-steps [INCONSISTENCY]
res.write(fs.readFileSync(['public', path].join('/'))); // $ MISSING: Alert - not flagged because we have no array-steps
let parts = ['public', path];
parts = parts.map(x => x.toLowerCase());
res.write(fs.readFileSync(parts.join('/'))); // BAD - but not flagged because we have no array-steps [INCONSISTENCY]
res.write(fs.readFileSync(parts.join('/'))); // $ MISSING: Alert - not flagged because we have no array-steps
});
server.listen();

View File

@@ -8,8 +8,8 @@ var server = http.createServer(function(req, res) {
});
async function doRead(pathPromise) {
fs.readFileSync(await pathPromise); // NOT OK
pathPromise.then(path => fs.readFileSync(path)); // NO TOK
fs.readFileSync(await pathPromise); // $ Alert
pathPromise.then(path => fs.readFileSync(path)); // $ Alert
}
server.listen();

View File

@@ -3,15 +3,14 @@ var express = require('express');
var app = express();
app.get('/some/path', function(req, res) {
// BAD: loading a module based on un-sanitized query parameters
var m = require(req.param("module"));
var m = require(req.param("module")); // $ Alert - loading a module based on un-sanitized query parameters
});
const resolve = require("resolve");
app.get('/some/path', function(req, res) {
var module = resolve.sync(req.param("module")); // NOT OK - resolving module based on query parameters
var module = resolve.sync(req.param("module")); // $ Alert - resolving module based on query parameters
resolve(req.param("module"), { basedir: __dirname }, function(err, res) { // NOT OK - resolving module based on query parameters
resolve(req.param("module"), { basedir: __dirname }, function(err, res) { // $ Alert - resolving module based on query parameters
var module = res;
});
});

View File

@@ -4,25 +4,22 @@ let path = require('path');
var app = express();
app.get('/some/path/:x', function(req, res) {
// BAD: sending a file based on un-sanitized query parameters
res.sendFile(req.param("gimme"));
// BAD: same as above
res.sendfile(req.param("gimme"));
res.sendFile(req.param("gimme")); // $ Alert - sending a file based on un-sanitized query parameters
res.sendfile(req.param("gimme")); // $ Alert - same as above
// GOOD: ensures files cannot be accessed outside of root folder
// OK - ensures files cannot be accessed outside of root folder
res.sendFile(req.param("gimme"), { root: process.cwd() });
// GOOD: ensures files cannot be accessed outside of root folder
// OK - ensures files cannot be accessed outside of root folder
res.sendfile(req.param("gimme"), { root: process.cwd() });
// BAD: doesn't help if user controls root
res.sendFile(req.param("file"), { root: req.param("dir") });
res.sendFile(req.param("file"), { root: req.param("dir") }); // $ Alert - doesn't help if user controls root
let homeDir = path.resolve('.');
res.sendFile(homeDir + '/data/' + req.params.x); // OK: sendFile disallows ../
res.sendfile('data/' + req.params.x); // OK: sendfile disallows ../
res.sendFile(homeDir + '/data/' + req.params.x); // OK - sendFile disallows ../
res.sendfile('data/' + req.params.x); // OK - sendfile disallows ../
res.sendFile(path.resolve('data', req.params.x)); // NOT OK
res.sendfile(path.join('data', req.params.x)); // NOT OK
res.sendFile(path.resolve('data', req.params.x)); // $ Alert
res.sendfile(path.join('data', req.params.x)); // $ Alert
res.sendFile(homeDir + path.join('data', req.params.x)); // kinda OK - can only escape from 'data/'

View File

@@ -4,28 +4,28 @@ var fs = require('fs'),
var server = http.createServer(function(req, res) {
let path = url.parse(req.url, true).query.path;
fs.readFileSync(path.substring(i, j)); // OK
fs.readFileSync(path.substring(4)); // NOT OK
fs.readFileSync(path.substring(0, i)); // NOT OK
fs.readFileSync(path.substr(4)); // NOT OK
fs.readFileSync(path.slice(4)); // NOT OK
fs.readFileSync(path.substring(i, j));
fs.readFileSync(path.substring(4)); // $ Alert
fs.readFileSync(path.substring(0, i)); // $ Alert
fs.readFileSync(path.substr(4)); // $ Alert
fs.readFileSync(path.slice(4)); // $ Alert
fs.readFileSync(path.concat(unknown)); // NOT OK
fs.readFileSync(unknown.concat(path)); // NOT OK
fs.readFileSync(unknown.concat(unknown, path)); // NOT OK
fs.readFileSync(path.concat(unknown)); // $ Alert
fs.readFileSync(unknown.concat(path)); // $ Alert
fs.readFileSync(unknown.concat(unknown, path)); // $ Alert
fs.readFileSync(path.trim()); // NOT OK
fs.readFileSync(path.toLowerCase()); // NOT OK
fs.readFileSync(path.trim()); // $ Alert
fs.readFileSync(path.toLowerCase()); // $ Alert
fs.readFileSync(path.split('/')); // OK (readFile throws an exception when the filename is an array)
fs.readFileSync(path.split('/')[0]); // OK -- for now
fs.readFileSync(path.split('/')[i]); // NOT OK
fs.readFileSync(path.split(/\//)[i]); // NOT OK
fs.readFileSync(path.split("?")[0]); // NOT OK
fs.readFileSync(path.split(unknown)[i]); // NOT OK -- but not yet flagged [INCONSISTENCY]
fs.readFileSync(path.split(unknown).whatever); // OK -- but still flagged [INCONSISTENCY]
fs.readFileSync(path.split(unknown)); // NOT OK
fs.readFileSync(path.split("?")[i]); // NOT OK -- but not yet flagged [INCONSISTENCY]
fs.readFileSync(path.split('/')); // OK - readFile throws an exception when the filename is an array
fs.readFileSync(path.split('/')[0]); // OK - for now
fs.readFileSync(path.split('/')[i]); // $ Alert
fs.readFileSync(path.split(/\//)[i]); // $ Alert
fs.readFileSync(path.split("?")[0]); // $ Alert
fs.readFileSync(path.split(unknown)[i]); // $ MISSING: Alert
fs.readFileSync(path.split(unknown).whatever); // $ SPURIOUS: Alert
fs.readFileSync(path.split(unknown)); // $ Alert
fs.readFileSync(path.split("?")[i]); // $ MISSING: Alert
});
server.listen();

View File

@@ -4,5 +4,5 @@ const parseTorrent = require('parse-torrent'),
function getTorrentData(dir, torrent){
let name = parseTorrent(torrent).name,
loc = dir + "/" + name + ".torrent.data";
return fs.readFileSync(loc); // NOT OK
return fs.readFileSync(loc); // $ Alert
}

View File

@@ -8,27 +8,26 @@ var fs = require('fs'),
var server = http.createServer(function(req, res) {
let path = url.parse(req.url, true).query.path;
// BAD: This could read any file on the file system
res.write(fs.readFileSync(path));
res.write(fs.readFileSync(path)); // $ Alert - This could read any file on the file system
if (path === 'foo.txt')
res.write(fs.readFileSync(path)); // GOOD: Path is compared to white-list
res.write(fs.readFileSync(path)); // OK - Path is compared to white-list
let path2 = path;
path2 ||= res.write(fs.readFileSync(path2)); // GOOD: path is falsy
path2 ||= res.write(fs.readFileSync(path2)); // OK - path is falsy
let path3 = path;
path3 &&= res.write(fs.readFileSync(path3)); // BAD: path is truthy
path3 &&= res.write(fs.readFileSync(path3)); // $ Alert - path is truthy
let path4 = path;
path4 ??= res.write(fs.readFileSync(path4)); // GOOD - path is null or undefined - but we don't capture that. [INCONSISTENCY]
path4 ??= res.write(fs.readFileSync(path4)); // $ SPURIOUS: Alert - path is null or undefined - but we don't capture that.
let path5 = path;
path5 &&= "clean";
res.write(fs.readFileSync(path5)); // GOOD: path is either falsy or "clean";
res.write(fs.readFileSync(path5)); // OK - path is either falsy or "clean";
let path6 = path;
path6 ||= "clean";
res.write(fs.readFileSync(path6)); // BAD: path can still be tainted
res.write(fs.readFileSync(path6)); // $ Alert - path can still be tainted
});

View File

@@ -50,6 +50,6 @@ function doZipSlip() {
files.push(name);
}
for (const file of files) {
fs.createWriteStream(path.join(extractTo, file)); // OK
fs.createWriteStream(path.join(extractTo, file));
}
}

View File

@@ -26,7 +26,7 @@ fs.createReadStream('archive.zip')
}
if (!fileName.startsWith(".")) {
entry.pipe(fs.createWriteStream(fileName)); // OK.
entry.pipe(fs.createWriteStream(fileName));
}
});
@@ -35,5 +35,5 @@ fs.createReadStream('archive.zip')
.on('entry', entry => {
const fileName = path.normalize(entry.path);
entry.pipe(fs.createWriteStream(path.basename(fileName))); // OK.
entry.pipe(fs.createWriteStream(path.basename(fileName)));
});

View File

@@ -1,3 +1,3 @@
exports.foo = function(req, res) {
res.render('foo', req.body); // NOT OK
res.render('foo', req.body); // $ Alert
}

View File

@@ -7,26 +7,26 @@ app.post('/path', function(req, res) {
var bodyParameter = req.body.bodyParameter;
var queryParameter = req.query.queryParameter;
res.render('template', bodyParameter); // NOT OK
res.render('template', queryParameter); // NOT OK
res.render('template', bodyParameter); // $ Alert
res.render('template', queryParameter); // $ Alert
if (typeof bodyParameter === "string") {
res.render('template', bodyParameter); // OK
res.render('template', bodyParameter);
}
res.render('template', queryParameter + ""); // OK
res.render('template', queryParameter + "");
res.render('template', {profile: bodyParameter}); // OK
res.render('template', {profile: bodyParameter});
indirect(res, queryParameter);
});
function indirect(res, obj) {
res.render("template", obj); // NOT OK
res.render("template", obj); // $ Alert
const str = obj + "";
res.render("template", str); // OK
res.render("template", str);
res.render("template", JSON.parse(str)); // NOT OK
res.render("template", JSON.parse(str)); // $ Alert
}
let routes = require('./routes');

View File

@@ -4,27 +4,27 @@ app.engine( '.hbs', handlebars({ defaultLayout: 'main', extname: '.hbs' }) );
app.set('view engine', '.hbs')
app.post('/path', require('body-parser').json(), function(req, res) {
var bodyParameter = req.body.bodyParameter;
res.render('template', bodyParameter); // NOT OK
res.render('template', bodyParameter); // $ Alert
});
var app2 = require('express')();
app2.post('/path', require('body-parser').json(), function(req, res) {
var bodyParameter = req.body.bodyParameter;
res.render('template', bodyParameter); // OK
res.render('template', bodyParameter);
});
var app3 = require('express')();
app3.set('view engine', 'pug');
app3.post('/path', require('body-parser').json(), function(req, res) {
var bodyParameter = req.body.bodyParameter;
res.render('template', bodyParameter); // OK
res.render('template', bodyParameter);
});
var app4 = require('express')();
app4.set('view engine', 'ejs');
app4.post('/path', require('body-parser').json(), function(req, res) {
var bodyParameter = req.body.bodyParameter;
res.render('template', bodyParameter); // NOT OK
res.render('template', bodyParameter); // $ Alert
});
var app5 = require('express')();
@@ -32,7 +32,7 @@ app5.engine("foobar", require("consolidate").whiskers);
app5.set('view engine', 'foobar');
app5.post('/path', require('body-parser').json(), function(req, res) {
var bodyParameter = req.body.bodyParameter;
res.render('template', bodyParameter); // NOT OK
res.render('template', bodyParameter); // $ Alert
});
var app6 = require('express')();
@@ -40,7 +40,7 @@ app6.register(".html", require("consolidate").whiskers);
app6.set('view engine', 'html');
app6.post('/path', require('body-parser').json(), function(req, res) {
var bodyParameter = req.body.bodyParameter;
res.render('template', bodyParameter); // NOT OK
res.render('template', bodyParameter); // $ Alert
});
const express = require('express');
@@ -49,6 +49,6 @@ var app7 = express();
app7.set('view engine', 'ejs');
router.post('/path', require('body-parser').json(), function(req, res) {
var bodyParameter = req.body.bodyParameter;
res.render('template', bodyParameter); // NOT OK
res.render('template', bodyParameter); // $ Alert
});
app7.use("/router", router);

View File

@@ -6,7 +6,7 @@ const { exec } = require('child_process');
function echo_title() {
// get the title from the event pull request
const title = github.context.payload.pull_request.title;
exec(`echo ${title}`, (err, stdout, stderr) => { // NOT OK
exec(`echo ${title}`, (err, stdout, stderr) => { // $ Alert
if (err) {
return;
}
@@ -16,7 +16,7 @@ function echo_title() {
// function which passes the issue title into an exec
function exec_head_ref() {
const head_ref = github.context.payload.pull_request.head.ref;
aexec.exec(`echo ${head_ref}`).then((res) => { // NOT OK
aexec.exec(`echo ${head_ref}`).then((res) => { // $ Alert
console.log(res);
});
}

View File

@@ -5,61 +5,61 @@ var cp = require("child_process"),
var server = http.createServer(function(req, res) {
let cmd = url.parse(req.url, true).query.path;
cp.exec("foo"); // OK
cp.execSync("foo"); // OK
cp.execFile("foo"); // OK
cp.execFileSync("foo"); // OK
cp.spawn("foo"); // OK
cp.spawnSync("foo"); // OK
cp.fork("foo"); // OK
cp.exec("foo");
cp.execSync("foo");
cp.execFile("foo");
cp.execFileSync("foo");
cp.spawn("foo");
cp.spawnSync("foo");
cp.fork("foo");
cp.exec(cmd); // NOT OK
cp.execSync(cmd); // NOT OK
cp.execFile(cmd); // NOT OK
cp.execFileSync(cmd); // NOT OK
cp.spawn(cmd); // NOT OK
cp.spawnSync(cmd); // NOT OK
cp.fork(cmd); // NOT OK
cp.exec(cmd); // $ Alert
cp.execSync(cmd); // $ Alert
cp.execFile(cmd); // $ Alert
cp.execFileSync(cmd); // $ Alert
cp.spawn(cmd); // $ Alert
cp.spawnSync(cmd); // $ Alert
cp.fork(cmd); // $ Alert
cp.exec("foo" + cmd + "bar"); // NOT OK
cp.exec("foo" + cmd + "bar"); // $ Alert
// These are technically NOT OK, but they are more likely as false positives
cp.exec("foo", {shell: cmd}); // OK
cp.exec("foo", {env: {PATH: cmd}}); // OK
cp.exec("foo", {cwd: cmd}); // OK
cp.exec("foo", {uid: cmd}); // OK
cp.exec("foo", {gid: cmd}); // OK
cp.exec("foo", {shell: cmd});
cp.exec("foo", {env: {PATH: cmd}});
cp.exec("foo", {cwd: cmd});
cp.exec("foo", {uid: cmd});
cp.exec("foo", {gid: cmd});
let sh, flag;
if (process.platform == 'win32')
sh = 'cmd.exe', flag = '/c';
else
sh = '/bin/sh', flag = '-c';
cp.spawn(sh, [ flag, cmd ]); // NOT OK
cp.spawn(sh, [ flag, cmd ]); // $ Alert
let args = [];
args[0] = "-c";
args[1] = cmd; // NOT OK
args[1] = cmd; // $ Alert
cp.execFile("/bin/bash", args);
let args = [];
args[0] = "-c";
args[1] = cmd; // NOT OK
args[1] = cmd; // $ Alert
run("sh", args);
let args = [];
args[0] = `-` + "c";
args[1] = cmd; // NOT OK
args[1] = cmd; // $ Alert
cp.execFile(`/bin` + "/bash", args);
cp.spawn('cmd.exe', ['/C', 'foo'].concat(["bar", cmd])); // NOT OK
cp.spawn('cmd.exe', ['/C', 'foo'].concat(cmd)); // NOT OK
cp.spawn('cmd.exe', ['/C', 'foo'].concat(["bar", cmd])); // $ Alert
cp.spawn('cmd.exe', ['/C', 'foo'].concat(cmd)); // $ Alert
let myArgs = [];
myArgs.push(`-` + "c");
myArgs.push(cmd);
cp.execFile(`/bin` + "/bash", args); // NOT OK - but no support for `[].push()` for indirect arguments [INCONSISTENCY]
cp.execFile(`/bin` + "/bash", args); // $ MISSING: Alert - no support for `[].push()` for indirect arguments
});
@@ -72,7 +72,7 @@ var util = require("util")
http.createServer(function(req, res) {
let cmd = url.parse(req.url, true).query.path;
util.promisify(cp.exec)(cmd); // NOT OK
util.promisify(cp.exec)(cmd); // $ Alert
});
@@ -80,7 +80,7 @@ const webpackDevServer = require('webpack-dev-server');
new webpackDevServer(compiler, {
before: function (app) {
app.use(function (req, res, next) {
cp.exec(req.query.fileName); // NOT OK
cp.exec(req.query.fileName); // $ Alert
require("my-sub-lib").foo(req.query.fileName); // calls lib/subLib/index.js#foo
});
@@ -91,5 +91,5 @@ import Router from "koa-router";
const router = new Router();
router.get("/ping/:host", async (ctx) => {
cp.exec("ping " + ctx.params.host); // NOT OK
cp.exec("ping " + ctx.params.host); // $ Alert
});

View File

@@ -12,7 +12,7 @@ function getShell() {
function execSh(command, options) {
var shell = getShell()
return cp.spawn(shell.cmd, [shell.arg, command], options) // BAD
return cp.spawn(shell.cmd, [shell.arg, command], options) // $ Alert
}
http.createServer(function (req, res) {

View File

@@ -7,7 +7,7 @@ function getShell() {
}
function execSh(command, options) {
return cp.spawn(getShell(), ["-c", command], options) // BAD
return cp.spawn(getShell(), ["-c", command], options) // $ Alert
};
http.createServer(function (req, res) {

View File

@@ -11,7 +11,7 @@ function asyncEach(arr, iterator) {
}
function execEach(commands) {
asyncEach(commands, (command) => exec(command)); // NOT OK
asyncEach(commands, (command) => exec(command)); // $ Alert
};
require('http').createServer(function(req, res) {

View File

@@ -6,12 +6,12 @@ var app = express();
var exec = require("child_process").exec;
app.post('/profile', upload.single('avatar'), function (req, res, next) {
exec("touch " + req.file.originalname); // NOT OK
exec("touch " + req.file.originalname); // $ Alert
});
app.post('/photos/upload', upload.array('photos', 12), function (req, res, next) {
req.files.forEach(file => {
exec("touch " + file.originalname); // NOT OK
exec("touch " + file.originalname); // $ Alert
})
});
@@ -22,7 +22,7 @@ var Busboy = require('busboy');
http.createServer(function (req, res) {
var busboy = new Busboy({ headers: req.headers });
busboy.on('file', function (fieldname, file, filename, encoding, mimetype) {
exec("touch " + filename); // NOT OK
exec("touch " + filename); // $ Alert
});
req.pipe(busboy);
}).listen(8000);
@@ -33,12 +33,12 @@ app.post('/api/upload', (req, res, next) => {
let form = formidable({ multiples: true });
form.parse(req, (err, fields, files) => {
exec("touch " + fields.name); // NOT OK
exec("touch " + fields.name); // $ Alert
});
let form2 = new formidable.IncomingForm();
form2.parse(req, (err, fields, files) => {
exec("touch " + fields.name); // NOT OK
exec("touch " + fields.name); // $ Alert
});
});
@@ -50,13 +50,13 @@ http.createServer(function (req, res) {
var form = new multiparty.Form();
form.parse(req, function (err, fields, files) {
exec("touch " + fields.name); // NOT OK
exec("touch " + fields.name); // $ Alert
});
var form2 = new multiparty.Form();
form2.on('part', function (part) { // / file / field
exec("touch " + part.filename); // NOT OK
exec("touch " + part.filename); // $ Alert
});
form2.parse(req);

View File

@@ -4,32 +4,32 @@ var http = require("http"),
var server = http.createServer(function (req, res) {
let cmd = url.parse(req.url, true).query.path;
require("cross-spawn").sync(cmd); // NOT OK
require("execa").shell(cmd); // NOT OK
require("execa").shellSync(cmd); // NOT OK
require("execa").stdout(cmd); // NOT OK
require("execa").stderr(cmd); // NOT OK
require("execa").sync(cmd); // NOT OK
require("cross-spawn").sync(cmd); // $ Alert
require("execa").shell(cmd); // $ Alert
require("execa").shellSync(cmd); // $ Alert
require("execa").stdout(cmd); // $ Alert
require("execa").stderr(cmd); // $ Alert
require("execa").sync(cmd); // $ Alert
require("cross-spawn")(cmd); // NOT OK
require("cross-spawn-async")(cmd); // NOT OK
require("exec")(cmd); // NOT OK
require("exec-async")(cmd); // NOT OK
require("execa")(cmd); // NOT OK
require("remote-exec")(target, cmd); // NOT OK
require("cross-spawn")(cmd); // $ Alert
require("cross-spawn-async")(cmd); // $ Alert
require("exec")(cmd); // $ Alert
require("exec-async")(cmd); // $ Alert
require("execa")(cmd); // $ Alert
require("remote-exec")(target, cmd); // $ Alert
const ssh2 = require("ssh2");
new ssh2().exec(cmd); // NOT OK
new ssh2.Client().exec(cmd); // NOT OK
new ssh2().exec(cmd); // $ Alert
new ssh2.Client().exec(cmd); // $ Alert
const SSH2Stream = require("ssh2-streams").SSH2Stream;
new SSH2Stream().exec(false, cmd); // NOT OK
new SSH2Stream().exec(false, cmd); // $ Alert
require("execa").node(cmd); // NOT OK
require("execa").node(cmd); // $ Alert
require("foreground-child")(cmd); // NOT OK
require("foreground-child")(cmd); // $ Alert
const opener = require("opener");
opener("http://github.com/" + url.parse(req.url, true).query.user); // OK
opener("http://github.com", { command: cmd }); // NOT OK
opener("http://github.com/" + url.parse(req.url, true).query.user);
opener("http://github.com", { command: cmd }); // $ Alert
});

View File

@@ -1,14 +1,14 @@
import { exec } from "@actions/exec";
import { getInput } from "@actions/core";
exec(process.env['TEST_DATA']); // NOT OK
exec(process.env['GITHUB_ACTION']); // OK
exec(process.env['TEST_DATA']); // $ Alert
exec(process.env['GITHUB_ACTION']);
function test(e) {
exec(e['TEST_DATA']); // NOT OK
exec(e['GITHUB_ACTION']); // OK
exec(e['TEST_DATA']); // $ Alert
exec(e['GITHUB_ACTION']);
}
test(process.env);
exec(getInput('data')); // NOT OK
exec(getInput('data')); // $ Alert

View File

@@ -1,36 +1,36 @@
var cp = require("child_process");
(function() {
cp.exec(process.argv); // NOT OK (just weird)
cp.exec(process.argv[0]); // OK
cp.exec("cmd.sh " + process.argv[0]); // OK
cp.exec("cmd.sh " + process.argv[1]); // OK
cp.exec("cmd.sh " + process.argv[2]); // NOT OK
cp.exec(process.argv); // $ Alert - just weird
cp.exec(process.argv[0]);
cp.exec("cmd.sh " + process.argv[0]);
cp.exec("cmd.sh " + process.argv[1]);
cp.exec("cmd.sh " + process.argv[2]); // $ Alert
var args = process.argv.slice(2);
cp.execSync(args[0]); // NOT OK
cp.execSync("cmd.sh " + args[0]); // NOT OK
cp.execSync(args[0]); // $ Alert
cp.execSync("cmd.sh " + args[0]); // $ Alert
var fewerArgs = args.slice(1);
cp.execSync(fewerArgs[0]); // NOT OK
cp.execSync("cmd.sh " + fewerArgs[0]); // NOT OK
cp.execSync(fewerArgs[0]); // $ Alert
cp.execSync("cmd.sh " + fewerArgs[0]); // $ Alert
var arg0 = fewerArgs[0];
cp.execSync(arg0); // NOT OK
cp.execSync("cmd.sh " + arg0); // NOT OK
cp.execSync(arg0); // $ Alert
cp.execSync("cmd.sh " + arg0); // $ Alert
});
(function() {
const args = process.argv.slice(2);
const script = path.join(packageDir, 'app', 'index.js');
cp.execSync(`node ${script} ${args[0]} --option"`); // NOT OK
cp.execSync(`node ${script} ${args.join(' ')} --option"`); // NOT OK
cp.execSync(`node ${script} ${args[0]} --option"`); // $ Alert
cp.execSync(`node ${script} ${args.join(' ')} --option"`); // $ Alert
});
cp.exec("cmd.sh " + require("get-them-args")().foo); // NOT OK
cp.exec("cmd.sh " + require("get-them-args")().foo); // $ Alert
cp.exec("cmd.sh " + require("minimist")().foo); // OK - no args provided.
cp.exec("cmd.sh " + require("yargs").argv.foo); // NOT OK
cp.exec("cmd.sh " + require("optimist").argv.foo); // NOT OK
cp.exec("cmd.sh " + require("yargs").argv.foo); // $ Alert
cp.exec("cmd.sh " + require("optimist").argv.foo); // $ Alert
(function () {
var args = require('yargs') // eslint-disable-line
@@ -38,9 +38,9 @@ cp.exec("cmd.sh " + require("optimist").argv.foo); // NOT OK
.option('verbose', { foo: "bar" })
.argv
cp.exec("cmd.sh " + args); // NOT OK
cp.exec("cmd.sh " + args); // $ Alert
cp.exec("cmd.sh " + require("yargs").array("foo").parse().foo); // NOT OK
cp.exec("cmd.sh " + require("yargs").array("foo").parse().foo); // $ Alert
});
(function () {
@@ -52,7 +52,7 @@ cp.exec("cmd.sh " + require("optimist").argv.foo); // NOT OK
.usage('Usage: foo bar')
.command();
cp.exec("cmd.sh " + args); // NOT OK
cp.exec("cmd.sh " + args); // $ Alert
var tainted1 = require('yargs').argv;
var tainted2 = require('yargs').parse()
@@ -62,34 +62,34 @@ cp.exec("cmd.sh " + require("optimist").argv.foo); // NOT OK
taint2: tainted2
}
cp.exec("cmd.sh " + taint1rest); // NOT OK - has flow from tainted1
cp.exec("cmd.sh " + taint2rest); // NOT OK - has flow from tianted2
cp.exec("cmd.sh " + taint1rest); // $ Alert - has flow from tainted1
cp.exec("cmd.sh " + taint2rest); // $ Alert - has flow from tianted2
var {...taint3} = require('yargs').argv;
cp.exec("cmd.sh " + taint3); // NOT OK
cp.exec("cmd.sh " + taint3); // $ Alert
var [...taint4] = require('yargs').argv;
cp.exec("cmd.sh " + taint4); // NOT OK
cp.exec("cmd.sh " + taint4); // $ Alert
});
(function () {
const argv = process.argv.slice(2);
var minimist = require("minimist");
cp.exec("cmd.sh " + minimist(argv).foo); // NOT OK
cp.exec("cmd.sh " + minimist(argv).foo); // $ Alert
var subarg = require('subarg');
cp.exec("cmd.sh " + subarg(process.argv.slice(2)).foo); // NOT OK
cp.exec("cmd.sh " + subarg(process.argv.slice(2)).foo); // $ Alert
var yargsParser = require('yargs-parser');
cp.exec("cmd.sh " + yargsParser(process.argv.slice(2)).foo); // NOT OK
cp.exec("cmd.sh " + yargsParser(process.argv.slice(2)).foo); // $ Alert
import args from 'args'
var flags = args.parse(process.argv);
cp.exec("cmd.sh " + flags.foo); // NOT OK
cp.exec("cmd.sh " + flags.foo); // $ Alert
var flags = require('arg')({...spec});
cp.exec("cmd.sh " + flags.foo); // NOT OK
cp.exec("cmd.sh " + flags.foo); // $ Alert
})
(function () {
@@ -99,13 +99,13 @@ cp.exec("cmd.sh " + require("optimist").argv.foo); // NOT OK
parser.add_argument('-f', '--foo', { help: 'foo bar' });
cp.exec("cmd.sh " + parser.parse_args().foo); // NOT OK
cp.exec("cmd.sh " + parser.parse_args().foo); // $ Alert
});
(function () {
const commandLineArgs = require('command-line-args');
const options = commandLineArgs(optionDefinitions);
cp.exec("cmd.sh " + options.foo); // NOT OK
cp.exec("cmd.sh " + options.foo); // $ Alert
});
(function () {
@@ -113,7 +113,7 @@ cp.exec("cmd.sh " + require("optimist").argv.foo); // NOT OK
const cli = meow(`helpstring`, {flags: {...flags}});
cp.exec("cmd.sh " + cli.input[0]); // NOT OK
cp.exec("cmd.sh " + cli.input[0]); // $ Alert
});
(function () {
@@ -121,20 +121,20 @@ cp.exec("cmd.sh " + require("optimist").argv.foo); // NOT OK
var opts = dashdash.parse({options: options});
cp.exec("cmd.sh " + opts.foo); // NOT OK
cp.exec("cmd.sh " + opts.foo); // $ Alert
var parser = dashdash.createParser({options: options});
var opts = parser.parse();
cp.exec("cmd.sh " + opts.foo); // NOT OK
cp.exec("cmd.sh " + opts.foo); // $ Alert
});
(function () {
const { program } = require('commander');
program.version('0.0.1');
cp.exec("cmd.sh " + program.opts().pizzaType); // NOT OK
cp.exec("cmd.sh " + program.pizzaType); // NOT OK
cp.exec("cmd.sh " + program.opts().pizzaType); // $ Alert
cp.exec("cmd.sh " + program.pizzaType); // $ Alert
});
(function () {
@@ -142,8 +142,8 @@ cp.exec("cmd.sh " + require("optimist").argv.foo); // NOT OK
const program = new Command();
program.version('0.0.1');
cp.exec("cmd.sh " + program.opts().pizzaType); // NOT OK
cp.exec("cmd.sh " + program.pizzaType); // NOT OK
cp.exec("cmd.sh " + program.opts().pizzaType); // $ Alert
cp.exec("cmd.sh " + program.pizzaType); // $ Alert
cp.execFile(program.opts().pizzaType, ["foo", "bar"]); // OK
cp.execFile(program.opts().pizzaType, ["foo", "bar"]);
});

View File

@@ -4,18 +4,18 @@ const { execFile } = require("child_process");
app.get("/", (req, res) => {
const remote = req.query.remote;
execFile("git", ["ls-remote", remote]); // NOT OK
execFile("git", ["ls-remote", remote]); // $ Alert
execFile("git", ["fetch", remote]); // NOT OK
execFile("git", ["fetch", remote]); // $ Alert
indirect("git", ["ls-remote", remote]); // NOT OK
indirect("git", ["ls-remote", remote]); // $ Alert
const myArgs = req.query.args;
execFile("git", myArgs); // NOT OK
execFile("git", myArgs); // $ Alert
if (remote.startsWith("--")) {
execFile("git", ["ls-remote", remote, "HEAD"]); // OK - it is very explicit that options that allowed here.
execFile("git", ["ls-remote", remote, "HEAD"]); // OK - it is very explicit that options that allowed here.
} else {
execFile("git", ["ls-remote", remote, "HEAD"]); // OK - it's not an option
}
@@ -23,10 +23,10 @@ app.get("/", (req, res) => {
if (remote.startsWith("git@")) {
execFile("git", ["ls-remote", remote, "HEAD"]); // OK - it's a git URL
} else {
execFile("git", ["ls-remote", remote, "HEAD"]); // NOT OK - unknown starting string
execFile("git", ["ls-remote", remote, "HEAD"]); // $ Alert - unknown starting string
}
execFile("git", req.query.args); // NOT OK - unknown args
execFile("git", req.query.args); // $ Alert - unknown args
execFile("git", ["add", req.query.args]); // OK - git add is not a command that can be used to execute arbitrary code
@@ -34,16 +34,16 @@ app.get("/", (req, res) => {
execFile("git", ["ls-remote", req.query.remote].concat(req.query.otherArgs)); // NOT OK - but not found [INCONSISTENCY]. It's hard to track through concat.
execFile("git", ["add", "fpp"].concat(req.query.notVulnerable)); // OK
execFile("git", ["add", "fpp"].concat(req.query.notVulnerable));
// hg
execFile("hg", ["clone", req.query.remote]); // NOT OK
execFile("hg", ["clone", req.query.remote]); // $ Alert
execFile("hg", ["whatever", req.query.remote]); // NOT OK - `--config=alias.whatever=touch pwned`
execFile("hg", ["whatever", req.query.remote]); // $ Alert - `--config=alias.whatever=touch pwned`
execFile("hg", req.query.args); // NOT OK - unknown args
execFile("hg", req.query.args); // $ Alert - unknown args
execFile("hg", ["clone", "--", req.query.remote]); // OK
execFile("hg", ["clone", "--", req.query.remote]);
});
function indirect(cmd, args) {

View File

@@ -2,12 +2,12 @@ var cp = require('child_process'),
path = require('path'),
execa = require("execa");
(function() {
cp.execFileSync('rm', ['-rf', path.join(__dirname, "temp")]); // GOOD
cp.execSync('rm -rf ' + path.join(__dirname, "temp")); // BAD
cp.execFileSync('rm', ['-rf', path.join(__dirname, "temp")]);
cp.execSync('rm -rf ' + path.join(__dirname, "temp")); // $ Alert
execa.shell('rm -rf ' + path.join(__dirname, "temp")); // NOT OK
execa.shellSync('rm -rf ' + path.join(__dirname, "temp")); // NOT OK
execa.shell('rm -rf ' + path.join(__dirname, "temp")); // $ Alert
execa.shellSync('rm -rf ' + path.join(__dirname, "temp")); // $ Alert
const safe = "\"" + path.join(__dirname, "temp") + "\"";
execa.shellSync('rm -rf ' + safe); // OK
execa.shellSync('rm -rf ' + safe);
});

View File

@@ -3,5 +3,5 @@
const cp = require("child_process");
module.exports.thisMethodIsImported = function (name) {
cp.exec("rm -rf " + name); // NOT OK
cp.exec("rm -rf " + name); // $ Alert
}

View File

@@ -1,30 +1,30 @@
var cp = require("child_process")
module.exports = function (name) {
cp.exec("rm -rf " + name); // NOT OK
cp.exec("rm -rf " + name); // $ Alert
cp.execFile(name, [name]); // OK
cp.execFile(name, name); // OK
cp.execFile(name, [name]);
cp.execFile(name, name);
};
module.exports.foo = function (name) {
cp.exec("rm -rf " + name); // NOT OK
cp.exec("rm -rf " + name); // $ Alert
}
module.exports.foo.bar = function (name) {
cp.exec("rm -rf " + name); // NOT OK
cp.exec("rm -rf " + name); // $ Alert
}
function cla() { }
cla.prototype.method = function (name) {
cp.exec("rm -rf " + name); // NOT OK
cp.exec("rm -rf " + name); // $ Alert
}
module.exports = new cla();
function cla2() { }
cla2.prototype.method = function (name) {
cp.exec("rm -rf " + name); // NOT OK
cp.exec("rm -rf " + name); // $ Alert
}
module.exports.bla = new cla2();
@@ -32,29 +32,29 @@ module.exports.lib2 = require("./lib2.js")
class Cla3 {
constructor(name) {
cp.exec("rm -rf " + name); // NOT OK
cp.exec("rm -rf " + name); // $ Alert
}
static foo(name) {
cp.exec("rm -rf " + name); // NOT OK
cp.exec("rm -rf " + name); // $ Alert
}
bar(name) {
cp.exec("rm -rf " + name); // NOT OK
cp.exec("rm -rf " + name); // $ Alert
cp.exec("rm -rf " + notASource); // OK
cp.exec("rm -rf " + notASource);
}
}
module.exports.cla3 = Cla3;
module.exports.mz = function (name) {
require("mz/child_process").exec("rm -rf " + name); // NOT OK.
require("mz/child_process").exec("rm -rf " + name); // $ Alert
}
module.exports.flow = function (name) {
var cmd1 = "rm -rf " + name; // NOT OK.
var cmd1 = "rm -rf " + name; // $ Alert
cp.exec(cmd1);
var cmd2 = "rm -rf " + name; // NOT OK.
var cmd2 = "rm -rf " + name; // $ Alert
function myExec(cmd) {
cp.exec(cmd);
}
@@ -62,73 +62,73 @@ module.exports.flow = function (name) {
}
module.exports.stringConcat = function (name) {
cp.exec("rm -rf " + name); // NOT OK.
cp.exec("rm -rf " + name); // $ Alert
cp.exec(name); // OK.
cp.exec(name);
cp.exec("for foo in (" + name + ") do bla end"); // NOT OK.
cp.exec("for foo in (" + name + ") do bla end"); // $ Alert
cp.exec("cat /foO/BAR/" + name) // NOT OK.
cp.exec("cat /foO/BAR/" + name) // $ Alert
cp.exec("cat \"" + name + "\"") // NOT OK.
cp.exec("cat \"" + name + "\"") // $ Alert
cp.exec("cat '" + name + "'") // NOT OK.
cp.exec("cat '" + name + "'") // $ Alert
cp.exec("cat '/foo/bar" + name + "'") // NOT OK.
cp.exec("cat '/foo/bar" + name + "'") // $ Alert
cp.exec(name + " some file") // OK.
cp.exec(name + " some file")
}
module.exports.arrays = function (name) {
cp.exec("rm -rf " + name); // NOT OK.
cp.exec("rm -rf " + name); // $ Alert
var args1 = ["node"];
args1.push(name); // NOT OK.
args1.push(name); // $ Alert
cp.exec(args1.join(" "));
cp.exec(["rm -rf", name].join(" ")); // NOT OK.
cp.exec(["rm -rf", name].join(" ")); // $ Alert
cp.exec(["rm -rf", "\"" + name + "\""].join(" ")); // NOT OK.
cp.exec(["rm -rf", "\"" + name + "\""].join(" ")); // $ Alert
cp.execFile("rm", ["-rf", name]); // OK
cp.execFile("rm", ["-rf", name]);
}
var util = require("util");
module.exports.format = function (name) {
cp.exec(util.format("rm -rf %s", name)); // NOT OK
cp.exec(util.format("rm -rf %s", name)); // $ Alert
cp.exec(util.format("rm -rf '%s'", name)); // NOT OK
cp.exec(util.format("rm -rf '%s'", name)); // $ Alert
cp.exec(util.format("rm -rf '/foo/bar/%s'", name)); // NOT OK
cp.exec(util.format("rm -rf '/foo/bar/%s'", name)); // $ Alert
cp.exec(util.format("%s foo/bar", name)); // OK
cp.exec(util.format("%s foo/bar", name));
cp.exec(util.format("for foo in (%s) do bar end", name)); // OK
cp.exec(util.format("for foo in (%s) do bar end", name));
cp.exec(require("printf")('rm -rf %s', name)); // NOT OK
cp.exec(require("printf")('rm -rf %s', name)); // $ Alert
}
module.exports.valid = function (name) {
cp.exec("rm -rf " + name); // NOT OK
cp.exec("rm -rf " + name); // $ Alert
if (!isValidName(name)) {
return;
}
cp.exec("rm -rf " + name); // OK
cp.exec("rm -rf " + name);
}
module.exports.safe = function (name) {
cp.exec("rm -rf " + name); // NOT OK
cp.exec("rm -rf " + name); // $ Alert
if (!isSafeName(name)) {
return;
}
cp.exec("rm -rf " + name); // OK
cp.exec("rm -rf " + name);
}
class Cla4 {
wha(name) {
cp.exec("rm -rf " + name); // NOT OK
cp.exec("rm -rf " + name); // $ Alert
}
static bla(name) {
@@ -146,7 +146,7 @@ function Cla5(name) {
module.exports.cla5 = new Cla5();
module.exports.indirect = function (name) {
let cmd = "rm -rf " + name; // NOT OK
let cmd = "rm -rf " + name; // $ Alert
let sh = "sh";
let args = ["-c", cmd];
cp.spawn(sh, args, cb);
@@ -156,7 +156,7 @@ module.exports.indirect2 = function (name) {
let cmd = name;
let sh = "sh";
let args = ["-c", cmd];
cp.spawn(sh, args, cb); // OK
cp.spawn(sh, args, cb);
let cmd2 = "rm -rf " + name;
var args2 = [cmd2];
@@ -168,64 +168,64 @@ module.exports.indirect2 = function (name) {
}
module.exports.cmd = function (command, name) {
cp.exec("fo | " + command); // OK
cp.exec("fo | " + command);
cp.exec("fo | " + name); // NOT OK
cp.exec("fo | " + name); // $ Alert
}
module.exports.sanitizer = function (name) {
var sanitized = "'" + name.replace(/'/g, "'\\''") + "'"
cp.exec("rm -rf " + sanitized); // OK
cp.exec("rm -rf " + sanitized);
var broken = "'" + name.replace(/'/g, "'\''") + "'"
cp.exec("rm -rf " + broken); // NOT OK
cp.exec("rm -rf " + broken); // $ Alert
}
var path = require("path");
module.exports.guard = function (name) {
cp.exec("rm -rf " + name); // NOT OK
cp.exec("rm -rf " + name); // $ Alert
if (!path.exist(name)) {
cp.exec("rm -rf " + name); // NOT OK
cp.exec("rm -rf " + name); // $ Alert
return;
}
cp.exec("rm -rf " + name); // OK
cp.exec("rm -rf " + name);
}
module.exports.blacklistOfChars = function (name) {
cp.exec("rm -rf " + name); // NOT OK
cp.exec("rm -rf " + name); // $ Alert
if (/[^A-Za-z0-9_\/:=-]/.test(name)) {
cp.exec("rm -rf " + name); // NOT OK
cp.exec("rm -rf " + name); // $ Alert
} else {
cp.exec("rm -rf " + name); // OK
cp.exec("rm -rf " + name);
}
}
module.exports.whitelistOfChars = function (name) {
cp.exec("rm -rf " + name); // NOT OK
cp.exec("rm -rf " + name); // $ Alert
if (/^[A-Za-z0-9_\/:=-]$/.test(name)) {
cp.exec("rm -rf " + name); // OK
cp.exec("rm -rf " + name);
} else {
cp.exec("rm -rf " + name); // NOT OK
cp.exec("rm -rf " + name); // $ Alert
}
}
module.exports.blackList2 = function (name) {
cp.exec("rm -rf " + name); // NOT OK
cp.exec("rm -rf " + name); // $ Alert
if (!/^([a-zA-Z0-9]+))?$/.test(name)) {
cp.exec("rm -rf " + name); // NOT OK
cp.exec("rm -rf " + name); // $ Alert
process.exit(-1);
}
cp.exec("rm -rf " + name); // OK - but FP due to tracking flow through `process.exit()`. [INCONSISTENCY]
cp.exec("rm -rf " + name); // $ SPURIOUS: Alert - FP due to tracking flow through `process.exit()`.
}
module.exports.accessSync = function (name) {
cp.exec("rm -rf " + name); // NOT OK
cp.exec("rm -rf " + name); // $ Alert
try {
path.accessSync(name);
@@ -233,7 +233,7 @@ module.exports.accessSync = function (name) {
return;
}
cp.exec("rm -rf " + name); // OK - but FP due to `path.accessSync` not being recognized as a sanitizer. [INCONSISTENCY]
cp.exec("rm -rf " + name); // $ SPURIOUS: Alert - FP due to `path.accessSync` not being recognized as a sanitizer.
}
var cleanInput = function (s) {
@@ -246,39 +246,39 @@ var cleanInput = function (s) {
}
module.exports.goodSanitizer = function (name) {
cp.exec("rm -rf " + name); // NOT OK
cp.exec("rm -rf " + name); // $ Alert
var cleaned = cleanInput(name);
cp.exec("rm -rf " + cleaned); // OK - But FP due to SanitizingRegExpTest not being able to generate a barrier edge for an edge into a phi node.
cp.exec("rm -rf " + cleaned); // $ SPURIOUS: Alert - SanitizingRegExpTest is not able to generate a barrier edge for an edge into a phi node.
}
var fs = require("fs");
module.exports.guard2 = function (name) {
cp.exec("rm -rf " + name); // NOT OK
cp.exec("rm -rf " + name); // $ Alert
if (!fs.existsSync("prefix/" + name)) {
cp.exec("rm -rf prefix/" + name); // NOT OK
cp.exec("rm -rf prefix/" + name); // $ Alert
return;
}
cp.exec("rm -rf prefix/" + name); // OK
cp.exec("rm -rf prefix/" + name);
}
module.exports.sanitizerProperty = function (obj) {
cp.exec("rm -rf " + obj.version); // NOT OK
cp.exec("rm -rf " + obj.version); // $ Alert
obj.version = "";
cp.exec("rm -rf " + obj.version); // OK
cp.exec("rm -rf " + obj.version);
}
module.exports.Foo = class Foo {
start(opts) {
cp.exec("rm -rf " + opts.bla); // NOT OK
cp.exec("rm -rf " + opts.bla); // $ Alert
this.opts = {};
this.opts.bla = opts.bla
cp.exec("rm -rf " + this.opts.bla); // NOT OK
cp.exec("rm -rf " + this.opts.bla); // $ Alert
}
}
@@ -305,24 +305,24 @@ function sanitizeShellString(str) {
}
module.exports.sanitizer2 = function (name) {
cp.exec("rm -rf " + name); // NOT OK
cp.exec("rm -rf " + name); // $ Alert
var sanitized = sanitizeShellString(name);
cp.exec("rm -rf " + sanitized); // OK
cp.exec("rm -rf " + sanitized);
}
module.exports.typeofcheck = function (name) {
cp.exec("rm -rf " + name); // NOT OK
cp.exec("rm -rf " + name); // $ Alert
if (typeof name === "undefined") {
cp.exec("rm -rf " + name); // OK
cp.exec("rm -rf " + name);
} else {
cp.exec("rm -rf " + name); // NOT OK
cp.exec("rm -rf " + name); // $ Alert
}
}
module.exports.typeofcheck = function (arg) {
var cmd = "MyWindowCommand | findstr /i /c:" + arg; // NOT OK
var cmd = "MyWindowCommand | findstr /i /c:" + arg; // $ Alert
cp.exec(cmd);
}
@@ -333,22 +333,22 @@ function id(x) {
module.exports.id = id;
module.exports.unproblematic = function() {
cp.exec("rm -rf " + id("test")); // OK
cp.exec("rm -rf " + id("test"));
};
module.exports.problematic = function(n) {
cp.exec("rm -rf " + id(n)); // NOT OK
cp.exec("rm -rf " + id(n)); // $ Alert
};
module.exports.typeofNumber = function(n) {
if (typeof n === "number") {
cp.exec("rm -rf " + n); // OK
cp.exec("rm -rf " + n);
}
};
function boundProblem(safe, unsafe) {
cp.exec("rm -rf " + safe); // OK
cp.exec("rm -rf " + unsafe); // NOT OK
cp.exec("rm -rf " + safe);
cp.exec("rm -rf " + unsafe); // $ Alert
}
Object.defineProperty(module.exports, "boundProblem", {
@@ -363,7 +363,7 @@ function MyTrainer(opts) {
MyTrainer.prototype = {
train: function() {
var command = "learn " + this.learn_args + " " + model; // NOT OK
var command = "learn " + this.learn_args + " " + model; // $ Alert
cp.exec(command);
}
};
@@ -403,27 +403,27 @@ function yetAnohterSanitizer(str) {
}
module.exports.sanitizer3 = function (name) {
cp.exec("rm -rf " + name); // NOT OK
cp.exec("rm -rf " + name); // $ Alert
var sanitized = yetAnohterSanitizer(name);
cp.exec("rm -rf " + sanitized); // OK
cp.exec("rm -rf " + sanitized);
}
const cp = require("child_process");
const spawn = cp.spawn;
module.exports.shellOption = function (name) {
cp.exec("rm -rf " + name); // NOT OK
cp.exec("rm -rf " + name); // $ Alert
cp.execFile("rm", ["-rf", name], {shell: true}, (err, out) => {}); // NOT OK
cp.spawn("rm", ["-rf", name], {shell: true}); // NOT OK
cp.execFileSync("rm", ["-rf", name], {shell: true}); // NOT OK
cp.spawnSync("rm", ["-rf", name], {shell: true}); // NOT OK
cp.execFile("rm", ["-rf", name], {shell: true}, (err, out) => {}); // $ Alert
cp.spawn("rm", ["-rf", name], {shell: true}); // $ Alert
cp.execFileSync("rm", ["-rf", name], {shell: true}); // $ Alert
cp.spawnSync("rm", ["-rf", name], {shell: true}); // $ Alert
const SPAWN_OPT = {shell: true};
spawn("rm", ["first", name], SPAWN_OPT); // NOT OK
spawn("rm", ["first", name], SPAWN_OPT); // $ Alert
var arr = [];
arr.push(name); // NOT OK
arr.push(name); // $ Alert
spawn("rm", arr, SPAWN_OPT);
spawn("rm", build("node", (name ? name + ':' : '') + '-'), SPAWN_OPT); // This is bad, but the alert location is down in `build`.
}
@@ -433,18 +433,18 @@ function build(first, last) {
if (something() === 'gm')
arr.push('convert');
first && arr.push(first);
last && arr.push(last); // NOT OK
last && arr.push(last); // $ Alert
return arr;
};
var asyncExec = require("async-execute");
module.exports.asyncStuff = function (name) {
asyncExec("rm -rf " + name); // NOT OK
asyncExec("rm -rf " + name); // $ Alert
}
const myFuncs = {
myFunc: function (name) {
asyncExec("rm -rf " + name); // NOT OK
asyncExec("rm -rf " + name); // $ Alert
}
};
@@ -475,12 +475,12 @@ const {promisify} = require('util');
const exec = promisify(require('child_process').exec);
module.exports = function check(config) {
const cmd = path.join(config.installedPath, 'myBinary -v'); // NOT OK
const cmd = path.join(config.installedPath, 'myBinary -v'); // $ Alert
return exec(cmd);
}
module.exports.splitConcat = function (name) {
let args = ' my name is ' + name; // NOT OK
let args = ' my name is ' + name; // $ Alert
let cmd = 'echo';
cp.exec(cmd + args);
}
@@ -496,7 +496,7 @@ module.exports.myCommand = function (myCommand) {
};
module.exports.myIndirectThing = function (name) {
MyThing.cp.exec("rm -rf " + name); // NOT OK
MyThing.cp.exec("rm -rf " + name); // $ Alert
}
});
@@ -507,49 +507,49 @@ for (var name in imp){
}
module.exports.sanitizer4 = function (name) {
cp.exec("rm -rf " + name); // NOT OK
cp.exec("rm -rf " + name); // $ Alert
if (isNaN(name)) {
cp.exec("rm -rf " + name); // NOT OK
cp.exec("rm -rf " + name); // $ Alert
} else {
cp.exec("rm -rf " + name); // OK
cp.exec("rm -rf " + name);
}
if (isNaN(parseInt(name))) {
cp.exec("rm -rf " + name); // NOT OK
cp.exec("rm -rf " + name); // $ Alert
} else {
cp.exec("rm -rf " + name); // OK
cp.exec("rm -rf " + name);
}
if (isNaN(+name)) {
cp.exec("rm -rf " + name); // NOT OK
cp.exec("rm -rf " + name); // $ Alert
} else {
cp.exec("rm -rf " + name); // OK
cp.exec("rm -rf " + name);
}
if (isNaN(parseInt(name, 10))) {
cp.exec("rm -rf " + name); // NOT OK
cp.exec("rm -rf " + name); // $ Alert
} else {
cp.exec("rm -rf " + name); // OK
cp.exec("rm -rf " + name);
}
if (isNaN(name - 0)) {
cp.exec("rm -rf " + name); // NOT OK
cp.exec("rm -rf " + name); // $ Alert
} else {
cp.exec("rm -rf " + name); // OK
cp.exec("rm -rf " + name);
}
if (isNaN(name | 0)) { // <- not a sanitizer
cp.exec("rm -rf " + name); // NOT OK
cp.exec("rm -rf " + name); // $ Alert
} else {
cp.exec("rm -rf " + name); // NOT OK
cp.exec("rm -rf " + name); // $ Alert
}
}
module.exports.shellThing = function (name) {
function indirectShell(cmd, args, spawnOpts) {
cp.spawn(cmd, args, spawnOpts); // NOT OK
cp.spawn(cmd, args, spawnOpts); // $ Alert
}
indirectShell("rm", ["-rf", name], {shell: true});
@@ -557,40 +557,40 @@ module.exports.shellThing = function (name) {
module.exports.badSanitizer = function (name) {
if (!name.match(/^(.|\.){1,64}$/)) { // <- bad sanitizer
exec("rm -rf " + name); // NOT OK
exec("rm -rf " + name); // $ Alert
} else {
exec("rm -rf " + name); // NOT OK
exec("rm -rf " + name); // $ Alert
}
if (!name.match(/^\w{1,64}$/)) { // <- good sanitizer
exec("rm -rf " + name); // NOT OK
exec("rm -rf " + name); // $ Alert
} else {
exec("rm -rf " + name); // OK
exec("rm -rf " + name);
}
}
module.exports.safeWithBool = function (name) {
cp.exec("rm -rf " + name); // NOT OK
cp.exec("rm -rf " + name); // $ Alert
if (isSafeName(name)) {
cp.exec("rm -rf " + name); // OK
cp.exec("rm -rf " + name);
}
cp.exec("rm -rf " + name); // NOT OK
cp.exec("rm -rf " + name); // $ Alert
if (isSafeName(name) === true) {
cp.exec("rm -rf " + name); // OK
cp.exec("rm -rf " + name);
}
if (isSafeName(name) !== false) {
cp.exec("rm -rf " + name); // OK
cp.exec("rm -rf " + name);
}
if (isSafeName(name) == false) {
cp.exec("rm -rf " + name); // NOT OK
cp.exec("rm -rf " + name); // $ Alert
}
cp.exec("rm -rf " + name); // NOT OK
cp.exec("rm -rf " + name); // $ Alert
}
function indirectThing(name) {
@@ -606,36 +606,36 @@ function moreIndirect(name) {
}
module.exports.veryIndeirect = function (name) {
cp.exec("rm -rf " + name); // NOT OK
cp.exec("rm -rf " + name); // $ Alert
if (indirectThing(name)) {
cp.exec("rm -rf " + name); // OK
cp.exec("rm -rf " + name);
}
if (indirectThing2(name)) {
cp.exec("rm -rf " + name); // OK
cp.exec("rm -rf " + name);
}
if (moreIndirect(name)) {
cp.exec("rm -rf " + name); // OK
cp.exec("rm -rf " + name);
}
if (moreIndirect(name) !== false) {
cp.exec("rm -rf " + name); // OK
cp.exec("rm -rf " + name);
} else {
cp.exec("rm -rf " + name); // NOT OK
cp.exec("rm -rf " + name); // $ Alert
}
cp.exec("rm -rf " + name); // NOT OK
cp.exec("rm -rf " + name); // $ Alert
}
module.exports.sanitizer = function (name) {
var sanitized = "'" + name.replace(new RegExp("\'"), "'\\''") + "'"
cp.exec("rm -rf " + sanitized); // NOT OK
cp.exec("rm -rf " + sanitized); // $ Alert
var sanitized = "'" + name.replace(new RegExp("\'", 'g'), "'\\''") + "'"
cp.exec("rm -rf " + sanitized); // OK
cp.exec("rm -rf " + sanitized);
var sanitized = "'" + name.replace(new RegExp("\'", unknownFlags()), "'\\''") + "'"
cp.exec("rm -rf " + sanitized); // OK -- Most likely should be okay and not flagged to reduce false positives.
cp.exec("rm -rf " + sanitized); // OK - Most likely should be okay and not flagged to reduce false positives.
}

View File

@@ -1,9 +1,9 @@
var cp = require("child_process")
module.exports = function (name) {
cp.exec("rm -rf " + name); // NOT OK - is imported from main module.
cp.exec("rm -rf " + name); // $ Alert - is imported from main module.
};
module.exports.foo = function (name) {
cp.exec("rm -rf " + name); // NOT OK - is imported from main module.
cp.exec("rm -rf " + name); // $ Alert - is imported from main module.
};

View File

@@ -1,5 +1,5 @@
var cp = require("child_process")
module.exports = function (name) {
cp.exec("rm -rf " + name); // OK, is not exported to a main-module.
cp.exec("rm -rf " + name); // OK - is not exported to a main-module.
};

View File

@@ -1,5 +1,5 @@
const cp = require("child_process");
module.exports = function (name) {
cp.exec("rm -rf " + name); // NOT OK - this function is exported from `amd.js`
cp.exec("rm -rf " + name); // $ Alert - this function is exported from `amd.js`
};

View File

@@ -1,15 +1,15 @@
var cp = require("child_process")
module.exports = function (name) {
cp.exec("rm -rf " + name); // NOT OK - functions exported as part of a submodule are also flagged.
cp.exec("rm -rf " + name); // $ Alert - functions exported as part of a submodule are also flagged.
};
module.exports.foo = function (name) {
cp.exec("rm -rf " + name); // NOT OK - this is being called explicitly from child_process-test.js
cp.exec("rm -rf " + name); // $ Alert - this is being called explicitly from child_process-test.js
};
module.exports.amd = require("./amd.js");
module.exports.arrToShell = function (cmd, arr) {
cp.spawn("echo", arr, {shell: true}); // NOT OK
cp.spawn("echo", arr, {shell: true}); // $ Alert
}

View File

@@ -1,5 +1,5 @@
var cp = require("child_process")
export default function (name) {
cp.exec("rm -rf " + name); // NOT OK - the "files" directory points to this file.
cp.exec("rm -rf " + name); // $ Alert - the "files" directory points to this file.
}

View File

@@ -1,5 +1,5 @@
var cp = require("child_process")
module.exports = function (name) {
cp.exec("rm -rf " + name); // NOT OK - the "files" directory points to this file.
cp.exec("rm -rf " + name); // $ Alert - the "files" directory points to this file.
};

View File

@@ -1,5 +1,5 @@
var cp = require("child_process")
module.exports = function (name) {
cp.exec("rm -rf " + name); // NOT OK - functions exported as part of a submodule are also flagged.
cp.exec("rm -rf " + name); // $ Alert - functions exported as part of a submodule are also flagged.
};

View File

@@ -1,5 +1,5 @@
const cp = require("child_process")
module.exports = function (name) {
cp.exec("rm -rf " + name); // NOT OK - functions exported as part of a submodule are also flagged.
cp.exec("rm -rf " + name); // $ Alert - functions exported as part of a submodule are also flagged.
};

View File

@@ -7,21 +7,21 @@ var spawnSync = child_process.spawnSync;
var fs = require('fs');
var app = express();
exec("cat foo/bar", function (err, out) {}); // NOT OK
exec("cat foo/bar", function (err, out) {}); // $ Alert
exec("cat /proc/" + id + "/status", function (err, out) { // NOT OK
exec("cat /proc/" + id + "/status", function (err, out) { // $ Alert
console.log(out);
});
execSync('cat /proc/cpuinfo').toString(); // NOT OK.
execSync('cat /proc/cpuinfo').toString(); // $ Alert
execSync(`cat ${newpath}`) // NOT OK
execSync(`cat ${newpath}`) // $ Alert
execSync('cat package.json | wc -l'); // OK - pipes!
execSync('cat /proc/cpuinfo /foo/bar').toString(); // OK multiple files.
execSync('cat /proc/cpuinfo /foo/bar').toString(); // OK - multiple files.
execSync(`cat ${newpath} /foo/bar`).toString(); // OK multiple files.
execSync(`cat ${newpath} /foo/bar`).toString(); // OK - multiple files.
exec(`cat ${newpath} | grep foo`, function (err, out) { }) // OK - pipes
@@ -29,73 +29,73 @@ execSync(`cat ${newpath}`, {uid: 1000}) // OK - non trivial options
exec('cat *.js | wc -l', { cwd: './' }, function (err, out) { }); // OK - wildcard and pipes
execSync(`cat foo/bar/${newpath}`); // NOT OK ("encoding" is used EXACTLY the same way in fs.readFileSync)
execSync(`cat foo/bar/${newpath}`); // $ Alert - "encoding" is used EXACTLY the same way in fs.readFileSync
execSync(`cat foo/bar/${newpath}`, {encoding: 'utf8'}); // NOT OK ("encoding" is used EXACTLY the same way in fs.readFileSync)
execSync(`cat foo/bar/${newpath}`, {encoding: 'utf8'}); // $ Alert - "encoding" is used EXACTLY the same way in fs.readFileSync
execSync("/bin/cat /proc/cpuinfo", { uid: 1000, gid: 1000, encoding: 'utf8'}); // OK (fs.readFileSync cannot emulate uid / gid))
execSync("/bin/cat /proc/cpuinfo", { uid: 1000, gid: 1000, encoding: 'utf8'}); // OK - (fs.readFileSync cannot emulate uid / gid))
execSync('cat /proc/cpuinfo > foo/bar/baz').toString(); // OK.
execSync('cat /proc/cpuinfo > foo/bar/baz').toString();
execSync(`cat ${newpath} > ${destpath}`).toString(); // OK.
execSync(`cat ${newpath} > ${destpath}`).toString();
execSync(`cat ${files.join(' ')} > ${outFile}`); // OK
execSync(`cat ${files.join(' ')} > ${outFile}`);
execSync(`cat ${files.join(' ')}`); // OK - but flagged - not just a simple file read [INCONSISTENCY]
execSync(`cat ${files.join(' ')}`); // $ SPURIOUS: Alert - - but flagged - not just a simple file read
exec("cat /proc/cpuinfo | grep name"); // OK - pipes
execSync(`cat ${newpath} | ${othertool}`); // OK - pipes
function cat(file) {
return execSync('cat ' + file).toString(); // NOT OK
return execSync('cat ' + file).toString(); // $ Alert
}
execSync("sh -c 'cat " + newpath + "'"); // NOT OK - but not flagged [INCONSISTENCY]
execSync("sh -c 'cat " + newpath + "'"); // $ MISSING: Alert
var execFile = child_process.execFile;
var execFileSync = child_process.execFileSync;
execFile('/bin/cat', [ 'pom.xml' ], function(error, stdout, stderr ) { // NOT OK
execFile('/bin/cat', [ 'pom.xml' ], function(error, stdout, stderr ) { // $ Alert
// Not using stderr
console.log(stdout);
});
execFile('/bin/cat', [ 'pom.xml' ], function(error, stdout, stderr ) { // OK. - stderr is used.
execFile('/bin/cat', [ 'pom.xml' ], function(error, stdout, stderr ) { // OK - - stderr is used.
console.log(stderr);
});
execFile('/bin/cat', [ 'pom.xml' ], {encoding: 'utf8'}, function(error, stdout, stderr ) { // NOT OK
execFile('/bin/cat', [ 'pom.xml' ], {encoding: 'utf8'}, function(error, stdout, stderr ) { // $ Alert
// Not using stderr
console.log(stdout);
});
execFileSync('/bin/cat', [ 'pom.xml' ], {encoding: 'utf8'}); // NOT OK
execFileSync('/bin/cat', [ 'pom.xml' ], {encoding: 'utf8'}); // $ Alert
execFileSync('/bin/cat', [ 'pom.xml' ]); // NOT OK
execFileSync('/bin/cat', [ 'pom.xml' ]); // $ Alert
var opts = {encoding: 'utf8'};
execFileSync('/bin/cat', [ 'pom.xml' ], opts); // NOT OK
execFileSync('/bin/cat', [ 'pom.xml' ], opts); // $ Alert
var anOptsFileNameThatIsTooLongToBePrintedByToString = {encoding: 'utf8'};
execFileSync('/bin/cat', [ 'pom.xml' ], anOptsFileNameThatIsTooLongToBePrintedByToString); // NOT OK
execFileSync('/bin/cat', [ 'pom.xml' ], anOptsFileNameThatIsTooLongToBePrintedByToString); // $ Alert
execFileSync('/bin/cat', [ 'pom.xml' ], {encoding: 'someEncodingValueThatIsCompletelyBogusAndTooLongForToString'}); // NOT OK
execFileSync('/bin/cat', [ 'pom.xml' ], {encoding: 'someEncodingValueThatIsCompletelyBogusAndTooLongForToString'}); // $ Alert
execFileSync('/bin/cat', [ "foo/" + newPath + "bar" ], {encoding: 'utf8'}); // NOT OK
execFileSync('/bin/cat', [ "foo/" + newPath + "bar" ], {encoding: 'utf8'}); // $ Alert
execSync('cat /proc/cpuinfo' + foo).toString(); // NOT OK.
execSync('cat /proc/cpuinfo' + foo).toString(); // $ Alert
execFileSync('/bin/cat', [ `foo/bar/${newpath}` ]); // NOT OK
execFileSync('/bin/cat', [ `foo/bar/${newpath}` ]); // $ Alert
execFileSync('node', [ `foo/bar/${newpath}` ]); // OK - not a call to cat
exec("cat foo/bar", function (err, out) {}); // NOT OK
exec("cat foo/bar", function (err, out) {}); // $ Alert
exec("cat foo/bar", (err, out) => {console.log(out)}); // NOT OK
exec("cat foo/bar", (err, out) => {console.log(out)}); // $ Alert
exec("cat foo/bar", (err, out) => doSomethingWith(out)); // NOT OK
exec("cat foo/bar", (err, out) => doSomethingWith(out)); // $ Alert
execFileSync('/bin/cat', [ 'pom.xml' ], unknownOptions); // OK - unknown options.
@@ -118,13 +118,13 @@ spawn('cat', { stdio: ['pipe', stdin, 'inherit'] }); // OK - Non trivial use. (B
cat.stdout.on('end', () => res.end());
})();
var dead = exec("cat foo/bar", (err, out) => {console.log(out)}); // NOT OK
var dead = exec("cat foo/bar", (err, out) => {console.log(out)}); // $ Alert
var notDead = exec("cat foo/bar", (err, out) => {console.log(out)}); // OK
var notDead = exec("cat foo/bar", (err, out) => {console.log(out)});
console.log(notDead);
(function () {
var dead = exec("cat foo/bar", (err, out) => {console.log(out)}); // NOT OK
var dead = exec("cat foo/bar", (err, out) => {console.log(out)}); // $ Alert
someCall(
exec("cat foo/bar", (err, out) => {console.log(out)}) // OK - non-trivial use of returned proccess.
@@ -133,34 +133,34 @@ console.log(notDead);
return exec("cat foo/bar", (err, out) => {console.log(out)}); // OK - non-trivial use of returned proccess.
})();
const stdout2 = execSync('cat /etc/dnsmasq.conf', { // NOT OK.
const stdout2 = execSync('cat /etc/dnsmasq.conf', { // $ Alert
encoding: 'utf8'
});
exec('/bin/cat', function (e, s) {}); // OK
exec('/bin/cat', function (e, s) {});
spawn("cat") // OK
spawn("cat")
var shelljs = require("shelljs");
shelljs.exec("cat foo/bar", (err, out) => {console.log(out)}); // NOT OK
shelljs.exec("cat foo/bar", {encoding: 'utf8'}); // NOT OK
shelljs.exec("cat foo/bar", {encoding: 'utf8'}, (err, out) => {console.log(out)}); // NOT OK
shelljs.exec("cat foo/bar", (err, out) => {console.log(out)}); // $ Alert
shelljs.exec("cat foo/bar", {encoding: 'utf8'}); // $ Alert
shelljs.exec("cat foo/bar", {encoding: 'utf8'}, (err, out) => {console.log(out)}); // $ Alert
let cspawn = require('cross-spawn');
cspawn('cat', ['foo/bar'], { encoding: 'utf8' }); // NOT OK
cspawn('cat', ['foo/bar'], { encoding: 'utf8' }, (err, out) => {console.log(out)}); // NOT OK
cspawn('cat', ['foo/bar'], (err, out) => {console.log(out)}); // NOT OK
cspawn('cat', ['foo/bar']); // NOT OK
cspawn('cat', (err, out) => {console.log(out)}); // OK
cspawn('cat', { encoding: 'utf8' }); // OK
cspawn('cat', ['foo/bar'], { encoding: 'utf8' }); // $ Alert
cspawn('cat', ['foo/bar'], { encoding: 'utf8' }, (err, out) => {console.log(out)}); // $ Alert
cspawn('cat', ['foo/bar'], (err, out) => {console.log(out)}); // $ Alert
cspawn('cat', ['foo/bar']); // $ Alert
cspawn('cat', (err, out) => {console.log(out)});
cspawn('cat', { encoding: 'utf8' });
let myResult = cspawn.sync('cat', ['foo/bar']); // NOT OK
let myResult = cspawn.sync('cat', ['foo/bar'], { encoding: 'utf8' }); // NOT OK
let myResult = cspawn.sync('cat', ['foo/bar']); // $ Alert
let myResult = cspawn.sync('cat', ['foo/bar'], { encoding: 'utf8' }); // $ Alert
var execmod = require('exec');
execmod("cat foo/bar", (err, out) => {console.log(out)}); // NOT OK
execmod("cat foo/bar", {encoding: 'utf8'}); // NOT OK
execmod("cat foo/bar", {encoding: 'utf8'}, (err, out) => {console.log(out)}); // NOT OK
execmod("cat foo/bar", (err, out) => {console.log(out)}); // $ Alert
execmod("cat foo/bar", {encoding: 'utf8'}); // $ Alert
execmod("cat foo/bar", {encoding: 'utf8'}, (err, out) => {console.log(out)}); // $ Alert

View File

@@ -1,16 +1,16 @@
this.addEventListener('message', function(event) {
document.write(event.data); // NOT OK
document.write(event.data); // $ Alert
})
this.addEventListener('message', function({data}) {
document.write(data); // NOT OK
document.write(data); // $ Alert
})
function test() {
function foo(x, event, y) {
document.write(x.data); // OK
document.write(event.data); // NOT OK
document.write(y.data); // OK
document.write(x.data);
document.write(event.data); // $ Alert
document.write(y.data);
}
window.addEventListener("message", foo.bind(null, {data: 'items'}));

View File

@@ -1,12 +1,12 @@
angular.module('myApp', [])
.directive('myCustomer', function() {
return {
templateUrl: "SAFE" // OK
templateUrl: "SAFE"
}
})
.directive('myCustomer', function() {
return {
templateUrl: Cookie.get("unsafe") // NOT OK
templateUrl: Cookie.get("unsafe") // $ Alert
}
});

View File

@@ -21,29 +21,29 @@ export class AppComponent implements OnInit {
) {}
ngOnInit() {
this.sanitizer.bypassSecurityTrustHtml(ɵgetDOM().getLocation().href); // NOT OK
this.sanitizer.bypassSecurityTrustHtml(ɵgetDOM().getLocation().href); // $ Alert
this.sanitizer.bypassSecurityTrustHtml(this.route.snapshot.params.foo); // NOT OK
this.sanitizer.bypassSecurityTrustHtml(this.route.snapshot.queryParams.foo); // NOT OK
this.sanitizer.bypassSecurityTrustHtml(this.route.snapshot.fragment); // NOT OK
this.sanitizer.bypassSecurityTrustHtml(this.route.snapshot.paramMap.get('foo')); // NOT OK
this.sanitizer.bypassSecurityTrustHtml(this.route.snapshot.queryParamMap.get('foo')); // NOT OK
this.sanitizer.bypassSecurityTrustHtml(this.route.snapshot.params.foo); // $ Alert
this.sanitizer.bypassSecurityTrustHtml(this.route.snapshot.queryParams.foo); // $ Alert
this.sanitizer.bypassSecurityTrustHtml(this.route.snapshot.fragment); // $ Alert
this.sanitizer.bypassSecurityTrustHtml(this.route.snapshot.paramMap.get('foo')); // $ Alert
this.sanitizer.bypassSecurityTrustHtml(this.route.snapshot.queryParamMap.get('foo')); // $ Alert
this.route.paramMap.subscribe(map => {
this.sanitizer.bypassSecurityTrustHtml(map.get('foo')); // NOT OK
this.sanitizer.bypassSecurityTrustHtml(map.get('foo')); // $ Alert
});
this.sanitizer.bypassSecurityTrustHtml(this.route.snapshot.url[1].path); // NOT OK - though depends on route config
this.sanitizer.bypassSecurityTrustHtml(this.route.snapshot.url[1].parameters.x); // NOT OK
this.sanitizer.bypassSecurityTrustHtml(this.route.snapshot.url[1].parameterMap.get('x')); // NOT OK
this.sanitizer.bypassSecurityTrustHtml(this.route.snapshot.url[1].parameterMap.params.x); // NOT OK
this.sanitizer.bypassSecurityTrustHtml(this.route.snapshot.url[1].path); // $ Alert - though depends on route config
this.sanitizer.bypassSecurityTrustHtml(this.route.snapshot.url[1].parameters.x); // $ Alert
this.sanitizer.bypassSecurityTrustHtml(this.route.snapshot.url[1].parameterMap.get('x')); // $ Alert
this.sanitizer.bypassSecurityTrustHtml(this.route.snapshot.url[1].parameterMap.params.x); // $ Alert
this.sanitizer.bypassSecurityTrustHtml(this.router.url); // NOT OK
this.sanitizer.bypassSecurityTrustHtml(this.router.url); // $ Alert
this.sanitizer2.bypassSecurityTrustHtml(this.router.url); // NOT OK
this.renderer.setProperty(this.document.documentElement, 'innerHTML', this.route.snapshot.queryParams.foo); // NOT OK
this.sanitizer2.bypassSecurityTrustHtml(this.router.url); // $ Alert
this.renderer.setProperty(this.document.documentElement, 'innerHTML', this.route.snapshot.queryParams.foo); // $ Alert
}
someMethod(routeSnapshot: ActivatedRouteSnapshot) {
this.sanitizer.bypassSecurityTrustHtml(routeSnapshot.paramMap.get('foo')); // NOT OK
this.sanitizer.bypassSecurityTrustHtml(routeSnapshot.paramMap.get('foo')); // $ Alert
}
}

View File

@@ -4,15 +4,15 @@ import classNamesB from 'classnames/bind';
import clsx from 'clsx';
function main() {
document.body.innerHTML = `<span class="${classNames(window.name)}">Hello<span>`; // NOT OK
document.body.innerHTML = `<span class="${classNamesD(window.name)}">Hello<span>`; // NOT OK
document.body.innerHTML = `<span class="${classNamesB(window.name)}">Hello<span>`; // NOT OK
document.body.innerHTML = `<span class="${classNames(window.name)}">Hello<span>`; // $ Alert
document.body.innerHTML = `<span class="${classNamesD(window.name)}">Hello<span>`; // $ Alert
document.body.innerHTML = `<span class="${classNamesB(window.name)}">Hello<span>`; // $ Alert
let unsafeStyle = classNames.bind({foo: window.name});
document.body.innerHTML = `<span class="${unsafeStyle('foo')}">Hello<span>`; // NOT OK
document.body.innerHTML = `<span class="${unsafeStyle('foo')}">Hello<span>`; // $ Alert
let safeStyle = classNames.bind({});
document.body.innerHTML = `<span class="${safeStyle(window.name)}">Hello<span>`; // NOT OK
document.body.innerHTML = `<span class="${safeStyle('foo')}">Hello<span>`; // OK
document.body.innerHTML = `<span class="${clsx(window.name)}">Hello<span>`; // NOT OK
document.body.innerHTML = `<span class="${safeStyle(window.name)}">Hello<span>`; // $ Alert
document.body.innerHTML = `<span class="${safeStyle('foo')}">Hello<span>`;
document.body.innerHTML = `<span class="${clsx(window.name)}">Hello<span>`; // $ Alert
document.body.innerHTML += `<span class="${clsx(window.name)}">Hello<span>`; // NOT OK
document.body.innerHTML += `<span class="${clsx(window.name)}">Hello<span>`; // $ Alert
}

View File

@@ -12,7 +12,7 @@ function paste(e) {
const div = document.createElement('div');
if (html) {
div.innerHTML = html; // NOT OK
div.innerHTML = html; // $ Alert
} else {
div.textContent = text;
}
@@ -21,16 +21,16 @@ function paste(e) {
export function install(el: HTMLElement): void {
el.addEventListener('paste', (e) => {
$("#id").html(e.clipboardData.getData('text/html')); // NOT OK
$("#id").html(e.clipboardData.getData('text/html')); // $ Alert
})
}
document.addEventListener('paste', (e) => {
$("#id").html(e.clipboardData.getData('text/html')); // NOT OK
$("#id").html(e.clipboardData.getData('text/html')); // $ Alert
});
$("#foo").bind('paste', (e) => {
$("#id").html(e.originalEvent.clipboardData.getData('text/html')); // NOT OK
$("#id").html(e.originalEvent.clipboardData.getData('text/html')); // $ Alert
});
(function () {
@@ -47,7 +47,7 @@ $("#foo").bind('paste', (e) => {
const div = document.createElement('div');
if (html) {
div.innerHTML = html; // NOT OK
div.innerHTML = html; // $ Alert
} else {
div.textContent = text;
}
@@ -96,6 +96,6 @@ async function getClipboardData(e: ClipboardEvent): Promise<Array<File | string>
if (!dataTransfer) return;
const html = dataTransfer.getData('text/html');
$("#id").html(html); // NOT OK
$("#id").html(html); // $ Alert
});
})();

View File

@@ -2,6 +2,6 @@ import * as dummy from 'dummy';
class CustomElm extends HTMLElement {
test() {
this.innerHTML = window.name; // NOT OK
this.innerHTML = window.name; // $ Alert
}
}

View File

@@ -8,15 +8,15 @@ function doSomething() {
d3.select('#main')
.attr('width', 100)
.style('color', 'red')
.html(getTaint()) // NOT OK
.html(d => getTaint()) // NOT OK
.html(getTaint()) // $ Alert
.html(d => getTaint()) // $ Alert
.call(otherFunction)
.html(d => getTaint()); // NOT OK
.html(d => getTaint()); // $ Alert
}
function otherFunction(selection) {
selection
.attr('foo', 'bar')
.html(getTaint()); // NOT OK
.html(getTaint()); // $ Alert
}

View File

@@ -8,17 +8,17 @@ function main() {
let time = new Date();
let taint = decodeURIComponent(window.location.hash.substring(1));
document.body.innerHTML = `Time is ${dateFns.format(time, taint)}`; // NOT OK
document.body.innerHTML = `Time is ${dateFnsEsm.format(time, taint)}`; // NOT OK
document.body.innerHTML = `Time is ${dateFnsFp.format(taint)(time)}`; // NOT OK
document.body.innerHTML = `Time is ${dateFns.format(time, taint)}`; // $ Alert
document.body.innerHTML = `Time is ${dateFnsEsm.format(time, taint)}`; // $ Alert
document.body.innerHTML = `Time is ${dateFnsFp.format(taint)(time)}`; // $ Alert
document.body.innerHTML = `Time is ${dateFns.format(taint, time)}`; // OK - time arg is safe
document.body.innerHTML = `Time is ${dateFnsFp.format(time)(taint)}`; // OK - time arg is safe
document.body.innerHTML = `Time is ${moment(time).format(taint)}`; // NOT OK
document.body.innerHTML = `Time is ${moment(taint).format()}`; // OK
document.body.innerHTML = `Time is ${dateformat(time, taint)}`; // NOT OK
document.body.innerHTML = `Time is ${moment(time).format(taint)}`; // $ Alert
document.body.innerHTML = `Time is ${moment(taint).format()}`;
document.body.innerHTML = `Time is ${dateformat(time, taint)}`; // $ Alert
import dayjs from 'dayjs';
document.body.innerHTML = `Time is ${dayjs(time).format(taint)}`; // NOT OK
document.body.innerHTML = `Time is ${dayjs(time).format(taint)}`; // $ Alert
}
import LuxonAdapter from "@date-io/luxon";
@@ -34,10 +34,10 @@ function dateio() {
const moment = new MomentAdapter();
const dayjs = new DayJSAdapter();
document.body.innerHTML = `Time is ${dateFns.formatByString(new Date(), taint)}`; // NOT OK
document.body.innerHTML = `Time is ${luxon.formatByString(luxon.date(), taint)}`; // NOT OK
document.body.innerHTML = `Time is ${moment.formatByString(moment.date(), taint)}`; // NOT OK
document.body.innerHTML = `Time is ${dayjs.formatByString(dayjs.date(), taint)}`; // NOT OK
document.body.innerHTML = `Time is ${dateFns.formatByString(new Date(), taint)}`; // $ Alert
document.body.innerHTML = `Time is ${luxon.formatByString(luxon.date(), taint)}`; // $ Alert
document.body.innerHTML = `Time is ${moment.formatByString(moment.date(), taint)}`; // $ Alert
document.body.innerHTML = `Time is ${dayjs.formatByString(dayjs.date(), taint)}`; // $ Alert
}
import { DateTime } from "luxon";
@@ -45,18 +45,18 @@ import { DateTime } from "luxon";
function luxon() {
let taint = decodeURIComponent(window.location.hash.substring(1));
document.body.innerHTML = `Time is ${DateTime.now().plus({years: 1}).toFormat(taint)}`; // NOT OK
document.body.innerHTML = `Time is ${new DateTime().setLocale('fr').toFormat(taint)}`; // NOT OK
document.body.innerHTML = `Time is ${DateTime.fromISO("2020-01-01").startOf('day').toFormat(taint)}`; // NOT OK
document.body.innerHTML = `Time is ${DateTime.now().plus({years: 1}).toFormat(taint)}`; // $ Alert
document.body.innerHTML = `Time is ${new DateTime().setLocale('fr').toFormat(taint)}`; // $ Alert
document.body.innerHTML = `Time is ${DateTime.fromISO("2020-01-01").startOf('day').toFormat(taint)}`; // $ Alert
}
function dateio2() {
let taint = decodeURIComponent(window.location.hash.substring(1));
const moment = new MomentAdapter();
document.body.innerHTML = `Time is ${moment.addDays(moment.date("2020-06-21"), 1).format(taint)}`; // NOT OK
document.body.innerHTML = `Time is ${moment.addDays(moment.date("2020-06-21"), 1).format(taint)}`; // $ Alert
const luxon = new LuxonAdapter();
document.body.innerHTML = `Time is ${luxon.endOfDay(luxon.date()).toFormat(taint)}`; // NOT OK
document.body.innerHTML = `Time is ${luxon.endOfDay(luxon.date()).toFormat(taint)}`; // $ Alert
const dayjs = new DayJSAdapter();
document.body.innerHTML = `Time is ${dayjs.setHours(dayjs.date(), 4).format(taint)}`; // NOT OK
document.body.innerHTML = `Time is ${dayjs.setHours(dayjs.date(), 4).format(taint)}`; // $ Alert
}

View File

@@ -12,7 +12,7 @@ function drop(e) {
const div = document.createElement('div');
if (html) {
div.innerHTML = html; // NOT OK
div.innerHTML = html; // $ Alert
} else {
div.textContent = text;
}
@@ -21,16 +21,16 @@ function drop(e) {
export function install(el: HTMLElement): void {
el.addEventListener('drop', (e) => {
$("#id").html(e.dataTransfer.getData('text/html')); // NOT OK
$("#id").html(e.dataTransfer.getData('text/html')); // $ Alert
})
}
document.addEventListener('drop', (e) => {
$("#id").html(e.dataTransfer.getData('text/html')); // NOT OK
$("#id").html(e.dataTransfer.getData('text/html')); // $ Alert
});
$("#foo").bind('drop', (e) => {
$("#id").html(e.originalEvent.dataTransfer.getData('text/html')); // NOT OK
$("#id").html(e.originalEvent.dataTransfer.getData('text/html')); // $ Alert
});
(function () {
@@ -47,7 +47,7 @@ $("#foo").bind('drop', (e) => {
const div = document.createElement('div');
if (html) {
div.innerHTML = html; // NOT OK
div.innerHTML = html; // $ Alert
} else {
div.textContent = text;
}

View File

@@ -1,4 +1,4 @@
function test() {
let loc = window.location.href;
$('<a href="' + encodeURIComponent(loc) + '">click</a>'); // OK
$('<a href="' + encodeURIComponent(loc) + '">click</a>');
}

View File

@@ -1,3 +1,3 @@
document.getElementById('my-id').onclick = function() {
this.parentNode.innerHTML = '<h2><a href="' + location.href + '">A link</a></h2>'; // NOT OK
this.parentNode.innerHTML = '<h2><a href="' + location.href + '">A link</a></h2>'; // $ Alert
};

View File

@@ -3,9 +3,8 @@ var app = express();
import { JSDOM } from "jsdom";
app.get('/some/path', function (req, res) {
// NOT OK
new JSDOM(req.param("wobble"), { runScripts: "dangerously" });
new JSDOM(req.param("wobble"), { runScripts: "dangerously" }); // $ Alert
// OK
new JSDOM(req.param("wobble"), { runScripts: "outside-only" });
});

View File

@@ -2,37 +2,37 @@ function test() {
var tainted = document.location.search
$(tainted); // OK - location.search starts with '?'
$("body", tainted); // OK
$("." + tainted); // OK
$("<div id=\"" + tainted + "\">"); // NOT OK
$("body").html("XSS: " + tainted); // NOT OK
$("body", tainted);
$("." + tainted);
$("<div id=\"" + tainted + "\">"); // $ Alert
$("body").html("XSS: " + tainted); // $ Alert
$(window.location.hash); // OK - location.hash starts with '#'
$("<b>" + location.toString() + "</b>"); // NOT OK
$("<b>" + location.toString() + "</b>"); // $ Alert
// Not related to jQuery, but the handling of $() should not affect this sink
let elm = document.getElementById('x');
elm.innerHTML = decodeURIComponent(window.location.hash); // NOT OK
elm.innerHTML = decodeURIComponent(window.location.search); // NOT OK
elm.innerHTML = decodeURIComponent(window.location.toString()); // NOT OK
elm.innerHTML = decodeURIComponent(window.location.hash); // $ Alert
elm.innerHTML = decodeURIComponent(window.location.search); // $ Alert
elm.innerHTML = decodeURIComponent(window.location.toString()); // $ Alert
let hash = window.location.hash;
$(hash); // OK - start with '#'
$(hash.substring(1)); // NOT OK
$(hash.substring(1, 10)); // NOT OK
$(hash.substr(1)); // NOT OK
$(hash.slice(1)); // NOT OK
$(hash.substring(0, 10)); // OK
$(hash.substring(1)); // $ Alert
$(hash.substring(1, 10)); // $ Alert
$(hash.substr(1)); // $ Alert
$(hash.slice(1)); // $ Alert
$(hash.substring(0, 10));
$(hash.replace('#', '')); // NOT OK
$(window.location.search.replace('?', '')); // NOT OK
$(hash.replace('!', '')); // OK
$(hash.replace('blah', '')); // OK
$(hash.replace('#', '')); // $ Alert
$(window.location.search.replace('?', '')); // $ Alert
$(hash.replace('!', ''));
$(hash.replace('blah', ''));
$(hash + 'blah'); // OK
$(hash + 'blah');
$('blah' + hash); // OK - does not start with '<'
$('<b>' + hash + '</b>'); // NOT OK
$('<b>' + hash + '</b>'); // $ Alert
$('#foo').replaceWith(tainted); // NOT OK
$('#foo').replaceWith(() => tainted); // NOT OK
$('#foo').replaceWith(tainted); // $ Alert
$('#foo').replaceWith(() => tainted); // $ Alert
}

View File

@@ -28,15 +28,15 @@ app.get("/some/path", function (req, res) {
};
<script
type="application/ld+json"
dangerouslySetInnerHTML={{ __html: JSON.stringify(locale) }} // NOT OK
dangerouslySetInnerHTML={{ __html: JSON.stringify(locale) }} // $ Alert
/>;
<script
type="application/ld+json"
dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLD) }} // NOT OK
dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLD) }} // $ Alert
/>;
<script
type="application/ld+json"
dangerouslySetInnerHTML={{ __html: JSON.stringify({}) }} // OK
dangerouslySetInnerHTML={{ __html: JSON.stringify({}) }}
/>;
<script type="application/ld+json">{ JSON.stringify(jsonLD) }</script> // OK
<script type="application/ld+json">{ JSON.stringify(jsonLD) }</script>
});

View File

@@ -7,7 +7,6 @@ app.get('/some/path', function (req, res) {
var taint = req.param("wobble");
jwt.verify(taint, 'my-secret-key', function (err, decoded) {
// NOT OK
new JSDOM(decoded.foo, { runScripts: "dangerously" });
new JSDOM(decoded.foo, { runScripts: "dangerously" }); // $ Alert
});
});

View File

@@ -3,5 +3,5 @@ import $ from "jquery"
$.post(loginUrl(), {data: "foo"}, (data, xhr) => {
var decoded = jwt_decode(data);
$.jGrowl(decoded); // NOT OK - but only flagged with additional sources [INCONSISTENCY]
$.jGrowl(decoded); // $ MISSING: Alert - only flagged with additional sources
});

View File

@@ -9,7 +9,7 @@ app.post('/private_message', (req, res) => {
from: 'webmaster@example.com',
to: backend.getUserEmail(req.query.receiver),
subject: 'Private message',
text: `Hi, you got a message from someone. ${req.query.message}.`, // OK
html: `Hi, you got a message from someone. ${req.query.message}.`, // NOT OK
text: `Hi, you got a message from someone. ${req.query.message}.`,
html: `Hi, you got a message from someone. ${req.query.message}.`, // $ Alert
});
});

View File

@@ -1,24 +1,24 @@
function test() {
var target = document.location.search
$('myId').html(sanitize ? DOMPurify.sanitize(target) : target); // OK
$('myId').html(sanitize ? DOMPurify.sanitize(target) : target);
$('myId').html(target); // NOT OK
$('myId').html(target); // $ Alert
var tainted = target;
$('myId').html(tainted); // NOT OK
$('myId').html(tainted); // $ Alert
if (sanitize) {
tainted = DOMPurify.sanitize(tainted);
}
$('myId').html(tainted); // OK
$('myId').html(tainted);
inner(target);
function inner(x) {
$('myId').html(x); // NOT OK
$('myId').html(x); // $ Alert
if (sanitize) {
x = DOMPurify.sanitize(x);
}
$('myId').html(x); // OK
$('myId').html(x);
}
}
@@ -29,18 +29,18 @@ function badSanitizer() {
return x; // No sanitization;
}
var tainted2 = target;
$('myId').html(tainted2); // NOT OK
$('myId').html(tainted2); // $ Alert
if (sanitize) {
tainted2 = sanitizeBad(tainted2);
}
$('myId').html(tainted2); // NOT OK
$('myId').html(tainted2); // $ Alert
var tainted3 = target;
$('myId').html(tainted3); // NOT OK
$('myId').html(tainted3); // $ Alert
if (sanitize) {
tainted3 = sanitizeBad(tainted3);
}
$('myId').html(tainted3); // NOT OK
$('myId').html(tainted3); // $ Alert
$('myId').html(sanitize ? sanitizeBad(target) : target); // NOT OK
$('myId').html(sanitize ? sanitizeBad(target) : target); // $ Alert
}

View File

@@ -7,13 +7,13 @@ export default function Post(params) {
return (
<>
<div
dangerouslySetInnerHTML={{ __html: id }} // NOT OK
dangerouslySetInnerHTML={{ __html: id }} // $ Alert
/>
<div
dangerouslySetInnerHTML={{ __html: params.id }} // NOT OK
dangerouslySetInnerHTML={{ __html: params.id }} // $ Alert
/>
<div
dangerouslySetInnerHTML={{ __html: params.q }} // NOT OK
dangerouslySetInnerHTML={{ __html: params.q }} // $ Alert
/>
</>
)

View File

@@ -5,6 +5,6 @@ var app = express();
app.get('/some/path', function(req, res) {
let tainted = req.param("code");
<WebView html={tainted}/>; // NOT OK
<WebView source={{html: tainted}}/>; // NOT OK
<WebView html={tainted}/>; // $ Alert
<WebView source={{html: tainted}}/>; // $ Alert
});

View File

@@ -7,13 +7,13 @@ function useMyContext() {
export function useDoc1() {
let { root } = useMyContext();
root.appendChild(window.name); // NOT OK
root.appendChild(window.name); // $ Alert
}
class C extends Component {
foo() {
let { root } = this.context;
root.appendChild(window.name); // NOT OK
root.appendChild(window.name); // $ Alert
}
}

View File

@@ -5,13 +5,13 @@ export function nextRouter() {
return (
<div>
<span onClick={() => {
router.push(router.query.foobar) // NOT OK
router.push(router.query.foobar) // $ Alert
}}>Click to XSS 1</span>
<span onClick={() => {
router.replace(router.query.foobar) // NOT OK
router.replace(router.query.foobar) // $ Alert
}}>Click to XSS 2</span>
<span onClick={() => {
router.push('/?foobar=' + router.query.foobar) // OK
router.push('/?foobar=' + router.query.foobar)
}}>Safe Link</span>
</div>
)
@@ -20,7 +20,7 @@ export function nextRouter() {
import { withRouter } from 'next/router'
function Page({ router }) {
return <span onClick={() => router.push(router.query.foobar)}>Click to XSS 3</span> // NOT OK
return <span onClick={() => router.push(router.query.foobar)}>Click to XSS 3</span> // $ Alert
}
export const pageWithRouter = withRouter(Page);
@@ -30,7 +30,7 @@ export function nextRouterWithLib() {
return (
<div>
<span onClick={() => {
router.push(router.query.foobar) // NOT OK
router.push(router.query.foobar) // $ Alert
}}>Click to XSS 1</span>
</div>
)

View File

@@ -2,25 +2,25 @@ import { useState } from 'react';
function initialState() {
let [state, setState] = useState(window.name);
return <div dangerouslySetInnerHTML={{__html: state}}></div>; // NOT OK
return <div dangerouslySetInnerHTML={{__html: state}}></div>; // $ Alert
}
function setStateValue() {
let [state, setState] = useState('foo');
setState(window.name);
return <div dangerouslySetInnerHTML={{__html: state}}></div>; // NOT OK
return <div dangerouslySetInnerHTML={{__html: state}}></div>; // $ Alert
}
function setStateValueLazy() {
let [state, setState] = useState('foo');
setState(() => window.name);
return <div dangerouslySetInnerHTML={{__html: state}}></div>; // NOT OK
return <div dangerouslySetInnerHTML={{__html: state}}></div>; // $ Alert
}
function setStateValueLazy() {
let [state, setState] = useState('foo');
setState(prev => {
document.body.innerHTML = prev; // NOT OK
document.body.innerHTML = prev; // $ Alert
})
setState(() => window.name);
}
@@ -29,5 +29,5 @@ function setStateValueSafe() {
let [state, setState] = useState('foo');
setState('safe');
setState(() => 'also safe');
return <div dangerouslySetInnerHTML={{__html: state}}></div>; // OK
return <div dangerouslySetInnerHTML={{__html: state}}></div>;
}

View File

@@ -15,35 +15,35 @@ function escapeAttr(s) {
function test() {
var tainted = window.name;
var elt = document.createElement();
elt.innerHTML = "<a href=\"" + escapeAttr(tainted) + "\">" + escapeHtml(tainted) + "</a>"; // OK
elt.innerHTML = "<div>" + escapeAttr(tainted) + "</div>"; // NOT OK, but not flagged - [INCONSISTENCY]
elt.innerHTML = "<a href=\"" + escapeAttr(tainted) + "\">" + escapeHtml(tainted) + "</a>";
elt.innerHTML = "<div>" + escapeAttr(tainted) + "</div>"; // $ MISSING: Alert - not flagged -
const regex = /[<>'"&]/;
if (regex.test(tainted)) {
elt.innerHTML = '<b>' + tainted + '</b>'; // NOT OK
elt.innerHTML = '<b>' + tainted + '</b>'; // $ Alert
} else {
elt.innerHTML = '<b>' + tainted + '</b>'; // OK
elt.innerHTML = '<b>' + tainted + '</b>';
}
if (!regex.test(tainted)) {
elt.innerHTML = '<b>' + tainted + '</b>'; // OK
elt.innerHTML = '<b>' + tainted + '</b>';
} else {
elt.innerHTML = '<b>' + tainted + '</b>'; // NOT OK
elt.innerHTML = '<b>' + tainted + '</b>'; // $ Alert
}
if (regex.exec(tainted)) {
elt.innerHTML = '<b>' + tainted + '</b>'; // NOT OK
elt.innerHTML = '<b>' + tainted + '</b>'; // $ Alert
} else {
elt.innerHTML = '<b>' + tainted + '</b>'; // OK
elt.innerHTML = '<b>' + tainted + '</b>';
}
if (regex.exec(tainted) != null) {
elt.innerHTML = '<b>' + tainted + '</b>'; // NOT OK
elt.innerHTML = '<b>' + tainted + '</b>'; // $ Alert
} else {
elt.innerHTML = '<b>' + tainted + '</b>'; // OK
elt.innerHTML = '<b>' + tainted + '</b>';
}
if (regex.exec(tainted) == null) {
elt.innerHTML = '<b>' + tainted + '</b>'; // OK
elt.innerHTML = '<b>' + tainted + '</b>';
} else {
elt.innerHTML = '<b>' + tainted + '</b>'; // NOT OK
elt.innerHTML = '<b>' + tainted + '</b>'; // $ Alert
}
elt.innerHTML = tainted.replace(/<\w+/g, ''); // NOT OK
elt.innerHTML = tainted.replace(/<\w+/g, ''); // $ Alert
}

View File

@@ -2,29 +2,29 @@
sessionStorage.setItem('session', document.location.search);
localStorage.setItem('local', document.location.search);
$('myId').html(sessionStorage.getItem('session')); // NOT OK
$('myId').html(localStorage.getItem('session')); // OK
$('myId').html(sessionStorage.getItem('local')); // OK
$('myId').html(localStorage.getItem('local')); // NOT OK
$('myId').html(sessionStorage.getItem('session')); // $ Alert
$('myId').html(localStorage.getItem('session'));
$('myId').html(sessionStorage.getItem('local'));
$('myId').html(localStorage.getItem('local')); // $ Alert
var href = localStorage.getItem('local');
$('myId').html("<a href=\"" + href + ">foobar</a>"); // NOT OK
$('myId').html("<a href=\"" + href + ">foobar</a>"); // $ Alert
if (href.indexOf("\"") !== -1) {
return;
}
$('myId').html("<a href=\"" + href + "/>"); // OK
$('myId').html("<a href=\"" + href + "/>");
var href2 = localStorage.getItem('local');
if (href2.indexOf("\"") !== -1) {
return;
}
$('myId').html("\n<a href=\"" + href2 + ">foobar</a>"); // OK
$('myId').html("\n<a href=\"" + href2 + ">foobar</a>");
var href3 = localStorage.getItem('local');
if (href3.indexOf("\"") !== -1) {
return;
}
$('myId').html('\r\n<a href="/' + href3 + '">' + "something" + '</a>'); // OK
$('myId').html('\r\n<a href="/' + href3 + '">' + "something" + '</a>');
});

View File

@@ -1,12 +1,12 @@
document.write(document.location.href.charCodeAt(0)); // OK
document.write(document.location.href.charCodeAt(0));
document.write(document.location); // NOT OK
document.write(document.location.href); // NOT OK
document.write(document.location.href.valueOf()); // NOT OK
document.write(document.location.href.sup()); // NOT OK
document.write(document.location.href.toUpperCase()); // NOT OK
document.write(document.location.href.trimLeft()); // NOT OK
document.write(String.fromCharCode(document.location.href)); // NOT OK
document.write(String(document.location.href)); // NOT OK
document.write(escape(document.location.href)); // OK (for now)
document.write(escape(escape(escape(document.location.href)))); // OK (for now)
document.write(document.location); // $ Alert
document.write(document.location.href); // $ Alert
document.write(document.location.href.valueOf()); // $ Alert
document.write(document.location.href.sup()); // $ Alert
document.write(document.location.href.toUpperCase()); // $ Alert
document.write(document.location.href.trimLeft()); // $ Alert
document.write(String.fromCharCode(document.location.href)); // $ Alert
document.write(String(document.location.href)); // $ Alert
document.write(escape(document.location.href)); // OK - for now
document.write(escape(escape(escape(document.location.href)))); // OK - for now

View File

@@ -2,9 +2,9 @@ import 'dummy';
function foo(x, y, z) {
arguments; // ensure 'arguments' are used
document.writeln(x); // OK
document.writeln(y); // NOT OK
document.writeln(z); // OK
document.writeln(x);
document.writeln(y); // $ Alert
document.writeln(z);
}
function bar() {

View File

@@ -5,17 +5,17 @@ import ReactTooltip from 'react-tooltip';
function tooltips() {
const source = window.name;
return <span>
<span data-tip={source}/> // OK
<span data-tip={source} data-html={false} /> // OK
<span data-tip={source} data-html="true" /> // NOT OK
<span data-tip={source} data-html={true} /> // NOT OK
<span data-tip={source}/>
<span data-tip={source} data-html={false} />
<span data-tip={source} data-html="true" /> // $ Alert
<span data-tip={source} data-html={true} /> // $ Alert
<ReactTooltip />
</span>
}
function MyElement(props) {
const provide = props.provide;
return <div dangerouslySetInnerHTML={{__html: provide()}} />; // NOT OK
return <div dangerouslySetInnerHTML={{__html: provide()}} />; // $ Alert
}
function useMyElement() {

View File

@@ -5,8 +5,7 @@
};
var target = document.location.search
var searchParams = new URLSearchParams(target.substring(1));
// NOT OK
$('original-term').html(searchParams.get('term'));
// OK
$('original-term').html(searchParams.get('term')); // $ Alert
$('translated-term').html(translate[searchParams.get('term')]);
})();

View File

@@ -1,12 +1,12 @@
import * as lib from './trusted-types-lib';
const policy1 = trustedTypes.createPolicy('x', { createHTML: x => x }); // NOT OK
const policy1 = trustedTypes.createPolicy('x', { createHTML: x => x }); // $ Alert
policy1.createHTML(window.name);
const policy2 = trustedTypes.createPolicy('x', { createHTML: x => 'safe' }); // OK
const policy2 = trustedTypes.createPolicy('x', { createHTML: x => 'safe' });
policy2.createHTML(window.name);
const policy3 = trustedTypes.createPolicy('x', { createHTML: x => x }); // OK
const policy3 = trustedTypes.createPolicy('x', { createHTML: x => x });
policy3.createHTML('safe');
const policy4 = trustedTypes.createPolicy('x', { createHTML: lib.createHtml });

View File

@@ -1,144 +1,128 @@
function test() {
var target = document.location.search
// NOT OK
$('myId').html(target)
$('myId').html(target) // $ Alert
// NOT OK
document.write("<OPTION value=1>"+document.location.href.substring(document.location.href.indexOf("default=")+8)+"</OPTION>");
document.write("<OPTION value=1>"+document.location.href.substring(document.location.href.indexOf("default=")+8)+"</OPTION>"); // $ Alert
document.write("<OPTION value=2>English</OPTION>");
// NOT OK
$('<div style="width:' + target + 'px">');
$('<div style="width:' + target + 'px">'); // $ Alert
$('<div style="width:' + +target + 'px">'); // OK
$('<div style="width:' + parseInt(target) + 'px">'); // OK
$('<div style="width:' + +target + 'px">');
$('<div style="width:' + parseInt(target) + 'px">');
let params = (new URL(document.location)).searchParams;
$('name').html(params.get('name')); // NOT OK
$('name').html(params.get('name')); // $ Alert
var searchParams = new URLSearchParams(target.substring(1));
$('name').html(searchParams.get('name')); // NOT OK
$('name').html(searchParams.get('name')); // $ Alert
}
function foo(target) {
// NOT OK
$('myId').html(target);
$('myId').html(target); // $ Alert
}
foo(document.location.search);
function bar() {
return document.location.search;
}
// NOT OK
$('myId').html(bar());
$('myId').html(bar()); // $ Alert
function baz(x) {
return x;
}
// NOT OK
$('myId').html(baz(document.location.search));
$('myId').html(baz(document.location.search)); // $ Alert
function wrap(s) {
return "<div>" + s + "</div>";
}
// NOT OK
$('myId').html(wrap(document.location.search));
$('myId').html(wrap(document.location.search)); // $ Alert
function chop(s) {
if (s)
return s.substr(1);
return "";
}
// NOT OK
$('myId').html(chop(document.location.search));
// NOT OK (duplicated to test precision of flow tracking)
$('myId').html(chop(document.location.search));
// NOT OK
$('myId').html(wrap(chop(bar())));
$('myId').html(chop(document.location.search)); // $ Alert
$('myId').html(chop(document.location.search)); // $ Alert - duplicated to test precision of flow tracking
$('myId').html(wrap(chop(bar()))); // $ Alert
function dangerouslySetInnerHtml(s) {
// NOT OK
$('myId').html(s);
$('myId').html(s); // $ Alert
}
dangerouslySetInnerHtml(document.location.search);
dangerouslySetInnerHtml(document.location.search);
// NOT OK
$('myId').html(bar());
$('myId').html(bar()); // $ Alert
[,document.location.search].forEach(function(x) {
if (x)
// NOT OK
$('myId').html(x);
$('myId').html(x); // $ Alert
});
// NOT OK
let s = <span dangerouslySetInnerHTML={{__html: document.location.search}}/>;
let s = <span dangerouslySetInnerHTML={{__html: document.location.search}}/>; // $ Alert
angular.module('myApp', [])
.service("myService", function($sce, $other) {
$sce.trustAsHtml(document.location.search); // NOT OK
$sce.trustAsCss(document.location.search); // NOT OK
$sce.trustAsUNKNOWN(document.location.search); // OK
$sce.trustAs($sce.HTML, document.location.search); // NOT OK
$sce.trustAs($sce.CSS, document.location.search); // NOT OK
$sce.trustAs(UNKNOWN, document.location.search); // OK
$other.trustAsHtml(document.location.search); // OK
$sce.trustAsHtml(document.location.search); // $ Alert
$sce.trustAsCss(document.location.search); // $ Alert
$sce.trustAsUNKNOWN(document.location.search);
$sce.trustAs($sce.HTML, document.location.search); // $ Alert
$sce.trustAs($sce.CSS, document.location.search); // $ Alert
$sce.trustAs(UNKNOWN, document.location.search);
$other.trustAsHtml(document.location.search);
})
.service("myService2", function() {
angular.element('<div>').html(document.location.search); // NOT OK
angular.element('<div>').html('SAFE'); // OK
angular.element('<div>').html(document.location.search); // $ Alert
angular.element('<div>').html('SAFE');
})
.directive('myCustomer', function() {
return {
link: function(scope, element){
element.html(document.location.search); // NOT OK
element.html('SAFE'); // OK
element.html(document.location.search); // $ Alert
element.html('SAFE');
}
};
})
.service("myService3", function() {
angular.element(document.location.search); // NOT OK
angular.element('SAFE'); // OK
angular.element(document.location.search); // $ Alert
angular.element('SAFE');
})
function tst() {
var v = document.location.search.substr(1);
// NOT OK
document.write(v);
document.write(v); // $ Alert
if (/^\d+$/.test(v)) {
// OK
document.write(v);
}
if ((m = /^\d+$/.exec(v))) {
// OK
document.write(v);
}
if (v.match(/^\d+$/)) {
// OK
document.write(v);
}
if (v.match("^\\d+$")) {
// OK
document.write(v);
}
if (!(/\d+/.test(v))) // not effective - matches "123<script>...</script>"
return;
// NOT OK
document.write(v);
document.write(v); // $ Alert
if (!(/^\d+$/.test(v)))
return;
// OK
document.write(v);
}
@@ -148,11 +132,11 @@ function angularJSServices() {
xssSinkService1(window.location.search);
}])
.factory("xssSinkService1", function(){
return function(v){ $("<div>").html(v); } // NOT OK
return function(v){ $("<div>").html(v); } // $ Alert
})
.factory("xssSource_from_service", ["xssSourceService", function(xssSourceService){
$("<div>").html(xssSourceService()); // NOT OK
$("<div>").html(xssSourceService()); // $ Alert
}])
.factory("xssSourceService", function(){
return function() { return window.location.search };
@@ -162,11 +146,11 @@ function angularJSServices() {
xssSinkService2("innocent");
}])
.factory("xssSinkService2", function(){
return function(v){ $("<div>").html(v); } // OK
return function(v){ $("<div>").html(v); }
})
.factory("innocentSource_from_service", ["innocentSourceService", function(innocentSourceService){
$("<div>").html(innocentSourceService()); // OK
$("<div>").html(innocentSourceService());
}])
.factory("innocentSourceService", function(){
return function() { return "innocent" };
@@ -177,27 +161,27 @@ function testDOMParser() {
var target = document.location.search
var parser = new DOMParser();
parser.parseFromString(target, "application/xml"); // NOT OK
parser.parseFromString(target, "application/xml"); // $ Alert
}
function references() {
var tainted = document.location.search;
document.body.innerHTML = tainted; // NOT OK
document.body.innerHTML = tainted; // $ Alert
document.createElement().innerHTML = tainted; // NOT OK
createElement().innerHTML = tainted; // NOT OK
document.createElement().innerHTML = tainted; // $ Alert
createElement().innerHTML = tainted; // $ Alert
document.getElementsByClassName()[0].innerHTML = tainted; // NOT OK
getElementsByClassName()[0].innerHTML = tainted; // NOT OK
getElementsByClassName().item().innerHTML = tainted; // NOT OK
document.getElementsByClassName()[0].innerHTML = tainted; // $ Alert
getElementsByClassName()[0].innerHTML = tainted; // $ Alert
getElementsByClassName().item().innerHTML = tainted; // $ Alert
}
function react(){
var tainted = document.location.search;
React.createElement("div", {dangerouslySetInnerHTML: {__html: tainted}}); // NOT OK
React.createFactory("div")({dangerouslySetInnerHTML: {__html: tainted}}); // NOT OK
React.createElement("div", {dangerouslySetInnerHTML: {__html: tainted}}); // $ Alert
React.createFactory("div")({dangerouslySetInnerHTML: {__html: tainted}}); // $ Alert
class C1 extends React.Component {
constructor() {
@@ -209,26 +193,26 @@ function react(){
}
test() {
$('myId').html(this.state.tainted1); // NOT OK
$('myId').html(this.state.tainted2); // NOT OK
$('myId').html(this.state.tainted3); // NOT OK
$('myId').html(this.state.notTainted); // OK
$('myId').html(this.state.tainted1); // $ Alert
$('myId').html(this.state.tainted2); // $ Alert
$('myId').html(this.state.tainted3); // $ Alert
$('myId').html(this.state.notTainted);
this.setState(prevState => {
$('myId').html(prevState.tainted4) // NOT OK
$('myId').html(prevState.tainted4) // $ Alert
});
}
}
class C2 extends React.Component {
test() {
$('myId').html(this.props.tainted1); // NOT OK
$('myId').html(this.props.tainted2); // NOT OK
$('myId').html(this.props.tainted3); // NOT OK
$('myId').html(this.props.notTainted); // OK
$('myId').html(this.props.tainted1); // $ Alert
$('myId').html(this.props.tainted2); // $ Alert
$('myId').html(this.props.tainted3); // $ Alert
$('myId').html(this.props.notTainted);
this.setState((prevState, prevProps) => {
$('myId').html(prevProps.tainted4) // NOT OK
$('myId').html(prevProps.tainted4) // $ Alert
});
}
}
@@ -256,28 +240,28 @@ function react(){
}
function windowName() {
$(window.name); // NOT OK
$(name); // NOT OK
$(window.name); // $ Alert
$(name); // $ Alert
}
function windowNameAssigned() {
for (name of ['a', 'b']) {
$(window.name); // NOT OK
$(name); // OK
$(window.name); // $ Alert
$(name);
}
}
function jqueryLocation() {
$(location); // OK
$(window.location); // OK
$(document.location); // OK
$(location);
$(window.location);
$(document.location);
var loc1 = location;
var loc2 = window.location;
var loc3 = document.location;
$(loc1); // OK
$(loc2); // OK
$(loc3); // OK
$(loc1);
$(loc2);
$(loc3);
$("body").append(location); // NOT OK
$("body").append(location); // $ Alert
}
@@ -285,7 +269,7 @@ function testCreateContextualFragment() {
var tainted = window.name;
var range = document.createRange();
range.selectNode(document.getElementsByTagName("div").item(0));
var documentFragment = range.createContextualFragment(tainted); // NOT OK
var documentFragment = range.createContextualFragment(tainted); // $ Alert
document.body.appendChild(documentFragment);
}
@@ -293,14 +277,14 @@ function flowThroughPropertyNames() {
var obj = {};
obj[Math.random()] = window.name;
for (var p in obj)
$(p); // OK
$(p);
}
function basicExceptions() {
try {
throw location;
} catch(e) {
$("body").append(e); // NOT OK
$("body").append(e); // $ Alert
}
try {
@@ -308,18 +292,18 @@ function basicExceptions() {
throw location
} finally {}
} catch(e) {
$("body").append(e); // NOT OK
$("body").append(e); // $ Alert
}
}
function handlebarsSafeString() {
return new Handlebars.SafeString(location); // NOT OK!
return new Handlebars.SafeString(location); // $ Alert
}
function test2() {
var target = document.location.search
// OK
$('myId').html(target.length)
}
@@ -329,10 +313,10 @@ function getTaintedUrl() {
function URLPseudoProperties() {
let params = getTaintedUrl().searchParams;
$('name').html(params.get('name')); // NOT OK
$('name').html(params.get('name')); // $ Alert
let myUrl = getTaintedUrl();
$('name').html(myUrl.get('name')); // OK (.get is not defined on a URL)
$('name').html(myUrl.get('name')); // OK - .get is not defined on a URL
}
@@ -340,27 +324,27 @@ function hash() {
function getUrl() {
return new URL(document.location);
}
$(getUrl().hash.substring(1)); // NOT OK
$(getUrl().hash.substring(1)); // $ Alert
}
function growl() {
var target = document.location.search
$.jGrowl(target); // NOT OK
$.jGrowl(target); // $ Alert
}
function thisNodes() {
var pluginName = "myFancyJQueryPlugin";
var myPlugin = function () {
var target = document.location.search
this.html(target); // NOT OK. (this is a jQuery object)
this.innerHTML = target // OK. (this is a jQuery object)
this.html(target); // $ Alert - this is a jQuery object
this.innerHTML = target // OK - this is a jQuery object
this.each(function (i, e) {
this.innerHTML = target; // NOT OK. (this is a DOM-node);
this.html(target); // OK. (this is a DOM-node);
this.innerHTML = target; // $ Alert - (this is a DOM-node);
this.html(target); // OK - (this is a DOM-node);
e.innerHTML = target; // NOT OK.
e.innerHTML = target; // $ Alert
});
}
$.fn[pluginName] = myPlugin;
@@ -370,8 +354,7 @@ function thisNodes() {
function test() {
var target = document.location.search
// NOT OK
$('myId').html(target)
$('myId').html(target) // $ Alert
// OK - but only safe because contents are URI-encoded
$('myid').html(document.location.href.split("?")[0]);
@@ -381,68 +364,68 @@ function test() {
var target = document.location.search
$('myId').html(target); // NOT OK
$('myId').html(target); // $ Alert
$('myId').html(target.taint); // NOT OK
$('myId').html(target.taint); // $ Alert
target.taint2 = 2;
$('myId').html(target.taint2); // OK
$('myId').html(target.taint2);
target.taint3 = document.location.search;
$('myId').html(target.taint3); // NOT OK
$('myId').html(target.taint3); // $ Alert
target.sub.taint4 = 2
$('myId').html(target.sub.taint4); // OK
$('myId').html(target.sub.taint4);
$('myId').html(target.taint5); // NOT OK
$('myId').html(target.taint5); // $ Alert
target.taint5 = "safe";
target.taint6 = 2;
if (random()) {return;}
$('myId').html(target.taint6); // OK
$('myId').html(target.taint6);
if (random()) {target.taint7 = "safe";}
$('myId').html(target.taint7); // NOT OK
$('myId').html(target.taint7); // $ Alert
target.taint8 = target.taint8;
$('myId').html(target.taint8); // NOT OK
$('myId').html(target.taint8); // $ Alert
target.taint9 = (target.taint9 = "safe");
$('myId').html(target.taint9); // OK
$('myId').html(target.taint9);
}
function hash2() {
var payload = window.location.hash.substr(1);
document.write(payload); // NOT OK
document.write(payload); // $ Alert
let match = window.location.hash.match(/hello (\w+)/);
if (match) {
document.write(match[1]); // NOT OK
document.write(match[1]); // $ Alert
}
document.write(window.location.hash.split('#')[1]); // NOT OK
document.write(window.location.hash.split('#')[1]); // $ Alert
}
function nonGlobalSanitizer() {
var target = document.location.search
$("#foo").html(target.replace(/<metadata>[\s\S]*<\/metadata>/, '<metadata></metadata>')); // NOT OK
$("#foo").html(target.replace(/<metadata>[\s\S]*<\/metadata>/, '<metadata></metadata>')); // $ Alert
$("#foo").html(target.replace(/<|>/g, '')); // OK
$("#foo").html(target.replace(/<|>/g, ''));
}
function mootools(){
var source = document.location.search;
new Element("div"); // OK
new Element("div", {text: source}); // OK
new Element("div", {html: source}); // NOT OK
new Element("div").set("html", source); // NOT OK
new Element("div").set({"html": source}); // NOT OK
new Element("div").setProperty("html", source); // NOT OK
new Element("div").setProperties({"html": source}); // NOT OK
new Element("div").appendHtml(source); // NOT OK
new Element("div");
new Element("div", {text: source});
new Element("div", {html: source}); // $ Alert
new Element("div").set("html", source); // $ Alert
new Element("div").set({"html": source}); // $ Alert
new Element("div").setProperty("html", source); // $ Alert
new Element("div").setProperties({"html": source}); // $ Alert
new Element("div").appendHtml(source); // $ Alert
}
@@ -452,53 +435,53 @@ const ansiToHtml = new Convert();
function ansiToHTML() {
var source = document.location.search;
$("#foo").html(source); // NOT OK
$("#foo").html(ansiToHtml.toHtml(source)); // NOT OK
$("#foo").html(source); // $ Alert
$("#foo").html(ansiToHtml.toHtml(source)); // $ Alert
}
function domMethods() {
var source = document.location.search;
let table = document.getElementById('mytable');
table.innerHTML = source; // NOT OK
table.innerHTML = source; // $ Alert
let row = table.insertRow(-1);
row.innerHTML = source; // NOT OK
row.innerHTML = source; // $ Alert
let cell = row.insertCell();
cell.innerHTML = source; // NOT OK
cell.innerHTML = source; // $ Alert
}
function urlStuff() {
var url = document.location.search.substr(1);
$("<a>", {href: url}).appendTo("body"); // NOT OK
$("#foo").attr("href", url); // NOT OK
$("#foo").attr({href: url}); // NOT OK
$("<img>", {src: url}).appendTo("body"); // NOT OK
$("<a>", {href: win.location.href}).appendTo("body"); // OK
$("<a>", {href: url}).appendTo("body"); // $ Alert
$("#foo").attr("href", url); // $ Alert
$("#foo").attr({href: url}); // $ Alert
$("<img>", {src: url}).appendTo("body"); // $ Alert
$("<a>", {href: win.location.href}).appendTo("body");
$("<img>", {src: "http://google.com/" + url}).appendTo("body"); // OK
$("<img>", {src: "http://google.com/" + url}).appendTo("body");
$("<img>", {src: ["http://google.com", url].join("/")}).appendTo("body"); // OK
$("<img>", {src: ["http://google.com", url].join("/")}).appendTo("body");
if (url.startsWith("https://")) {
$("<img>", {src: url}).appendTo("body"); // OK
$("<img>", {src: url}).appendTo("body");
} else {
$("<img>", {src: url}).appendTo("body"); // NOT OK
$("<img>", {src: url}).appendTo("body"); // $ Alert
}
window.open(location.hash.substr(1)); // OK - any JavaScript is executed in another context
navigation.navigate(location.hash.substr(1)); // NOT OK
navigation.navigate(location.hash.substr(1)); // $ Alert
const myHistory = require('history').createBrowserHistory();
myHistory.push(location.hash.substr(1)); // NOT OK
myHistory.push(location.hash.substr(1)); // $ Alert
}
function Foo() {
this.foo = document;
var obj = {
bar: function() {
this.foo.body.innerHTML = decodeURI(window.location.hash); // NOT OK
this.foo.body.innerHTML = decodeURI(window.location.hash); // $ Alert
}
};
Object.assign(this, obj);
@@ -506,7 +489,7 @@ function Foo() {
function nonGlobalSanitizer() {
var target = document.location.search
$("#foo").html(target.replace(new RegExp("<|>"), '')); // NOT OK
$("#foo").html(target.replace(new RegExp("<|>", unknownFlags()), '')); // OK -- most likely good. We don't know what the flags are.
$("#foo").html(target.replace(new RegExp("<|>", "g"), '')); // OK
$("#foo").html(target.replace(new RegExp("<|>"), '')); // $ Alert
$("#foo").html(target.replace(new RegExp("<|>", unknownFlags()), '')); // OK - most likely good. We don't know what the flags are.
$("#foo").html(target.replace(new RegExp("<|>", "g"), ''));
}

View File

@@ -1,14 +1,14 @@
var foo = document.getElementById("foo");
var data = JSON.parse(decodeURIComponent(window.location.search.substr(1)));
foo.setAttribute("src", data.src); // NOT OK
foo.setAttribute("HREF", data.p); // NOT OK
foo.setAttribute("width", data.w); // OK
foo.setAttribute("xlink:href", data.p) // NOT OK
foo.setAttribute("src", data.src); // $ Alert
foo.setAttribute("HREF", data.p); // $ Alert
foo.setAttribute("width", data.w);
foo.setAttribute("xlink:href", data.p) // $ Alert
foo.setAttributeNS('xlink', 'href', data.p); // NOT OK
foo.setAttributeNS('foobar', 'href', data.p); // NOT OK
foo.setAttributeNS('baz', 'width', data.w); // OK
foo.setAttributeNS('xlink', 'href', data.p); // $ Alert
foo.setAttributeNS('foobar', 'href', data.p); // $ Alert
foo.setAttributeNS('baz', 'width', data.w);
for (var p in data)

View File

@@ -22,7 +22,7 @@
},
templates: {
suggestion: function(val) {
return val; // NOT OK
return val; // $ Alert
}
}
}

View File

@@ -1,15 +1,15 @@
function test() {
let tainted = document.location.search;
$("<div>" + tainted + "</div>"); // NOT OK
$(`<div>${tainted}</div>`); // NOT OK
$("<div>".concat(tainted).concat("</div>")); // NOT OK
$(["<div>", tainted, "</div>"].join()); // NOT OK
$("<div>" + tainted + "</div>"); // $ Alert
$(`<div>${tainted}</div>`); // $ Alert
$("<div>".concat(tainted).concat("</div>")); // $ Alert
$(["<div>", tainted, "</div>"].join()); // $ Alert
$("<div id=\"" + tainted + "\"/>"); // NOT OK
$(`<div id="${tainted}"/>`); // NOT OK
$("<div id=\"".concat(tainted).concat("/>")); // NOT OK
$(["<div id=\"", tainted, "\"/>"].join()); // NOT OK
$("<div id=\"" + tainted + "\"/>"); // $ Alert
$(`<div id="${tainted}"/>`); // $ Alert
$("<div id=\"".concat(tainted).concat("/>")); // $ Alert
$(["<div id=\"", tainted, "\"/>"].join()); // $ Alert
function indirection1(attrs) {
return '<div align="' + (attrs.defaultattr || 'left') + '">' + content + '</div>';
@@ -17,6 +17,6 @@ function test() {
function indirection2(attrs) {
return '<div align="'.concat(attrs.defaultattr || 'left').concat('">'.concat(content)).concat('</div>');
}
$(indirection1(document.location.search.attrs)); // NOT OK
$(indirection2(document.location.search.attrs)); // NOT OK
$(indirection1(document.location.search.attrs)); // $ Alert
$(indirection2(document.location.search.attrs)); // $ Alert
};

View File

@@ -8,7 +8,7 @@ ajv.addSchema({type: 'object', additionalProperties: {type: 'number'}}, 'pollDat
app.post('/polldata', (req, res) => {
if (!ajv.validate('pollData', req.body)) {
res.send(ajv.errorsText()); // NOT OK
res.send(ajv.errorsText()); // $ Alert
}
});
@@ -21,6 +21,6 @@ const joiSchema = joi.object().keys({
app.post('/votedata', (req, res) => {
const val = joiSchema.validate(req.body);
if (val.error) {
res.send(val.error); // NOT OK
res.send(val.error); // $ Alert
}
});

View File

@@ -8,31 +8,31 @@
try {
unknown(foo);
} catch (e) {
$('myId').html(e); // NOT OK!
$('myId').html(e); // $ Alert
}
try {
inner(foo);
} catch (e) {
$('myId').html(e); // NOT OK!
$('myId').html(e); // $ Alert
}
try {
unknown(foo + "bar");
} catch (e) {
$('myId').html(e); // NOT OK!
$('myId').html(e); // $ Alert
}
try {
unknown({ prop: foo });
} catch (e) {
$('myId').html(e); // NOT OK! - but not detected due to not tainting object that have a tainted propety. [INCONSISTENCY]
$('myId').html(e); // $ MISSING: Alert - - but not detected due to not tainting object that have a tainted propety.
}
try {
unknown(["bar", foo]);
} catch (e) {
$('myId').html(e); // NOT OK!
$('myId').html(e); // $ Alert
}
function deep(x) {
@@ -45,13 +45,13 @@
try {
deep("bar" + foo);
} catch (e) {
$('myId').html(e); // NOT OK!
$('myId').html(e); // $ Alert
}
try {
var tmp = "bar" + foo;
} catch (e) {
$('myId').html(e); // OK
$('myId').html(e);
}
function safe(x) {
@@ -61,13 +61,13 @@
try {
safe(foo);
} catch (e) {
$('myId').html(e); // OK
$('myId').html(e);
}
try {
safe.call(null, foo);
} catch (e) {
$('myId').html(e); // OK
$('myId').html(e);
}
var myWeirdInner;
try {
@@ -75,12 +75,12 @@
inner(x);
}
} catch (e) {
$('myId').html(e); // OK
$('myId').html(e);
}
try {
myWeirdInner(foo);
} catch (e) {
$('myId').html(e); // NOT OK!
$('myId').html(e); // $ Alert
}
$('myId').html(foo); // Direct leak, reported by other query.
@@ -88,13 +88,13 @@
try {
unknown(foo.match(/foo/));
} catch (e) {
$('myId').html(e); // NOT OK!
$('myId').html(e); // $ Alert
}
try {
unknown([foo, "bar"]);
} catch (e) {
$('myId').html(e); // NOT OK!
$('myId').html(e); // $ Alert
}
try {
@@ -104,7 +104,7 @@
// nothing
}
} catch (e) {
$('myId').html(e); // NOT OK!
$('myId').html(e); // $ Alert
}
});
@@ -116,7 +116,7 @@ app.get('/user/:id', function (req, res) {
try {
unknown(req.params.id);
} catch (e) {
res.send("Exception: " + e); // NOT OK!
res.send("Exception: " + e); // $ Alert
}
});
@@ -127,7 +127,7 @@ app.get('/user/:id', function (req, res) {
try {
unknown(sessionStorage.getItem('exceptionSession'));
} catch (e) {
$('myId').html(e); // NOT OK
$('myId').html(e); // $ Alert
}
})();
@@ -135,10 +135,10 @@ app.get('/user/:id', function (req, res) {
app.get('/user/:id', function (req, res) {
unknown(req.params.id, (error, res) => {
if (error) {
$('myId').html(error); // NOT OK
$('myId').html(error); // $ Alert
return;
}
$('myId').html(res); // OK (for now?)
$('myId').html(res); // OK - for now?
});
});
@@ -146,25 +146,25 @@ app.get('/user/:id', function (req, res) {
var foo = document.location.search;
new Promise(resolve => unknown(foo, resolve)).catch((e) => {
$('myId').html(e); // NOT OK
$('myId').html(e); // $ Alert
});
try {
null[foo];
} catch (e) {
$('myId').html(e); // NOT OK
$('myId').html(e); // $ Alert
}
try {
unknown()[foo];
} catch (e) {
$('myId').html(e); // OK. We are not sure that `unknown()` is null-ish.
$('myId').html(e); // OK - We are not sure that `unknown()` is null-ish.
}
try {
"foo"[foo]
} catch (e) {
$('myId').html(e); // OK
$('myId').html(e);
}
function inner(tainted, resolve) {
@@ -172,16 +172,16 @@ app.get('/user/:id', function (req, res) {
}
new Promise(resolve => inner(foo, resolve)).catch((e) => {
$('myId').html(e); // NOT OK
$('myId').html(e); // $ Alert
});
})();
app.get('/user/:id', function (req, res) {
unknown(req.params.id, (error, res) => {
if (error) {
$('myId').html(error); // NOT OK
$('myId').html(error); // $ Alert
}
$('myId').html(res); // OK - does not contain an error, and `res` is otherwise unknown.
$('myId').html(res); // OK - does not contain an error, and `res` is otherwise unknown.
});
});
@@ -189,7 +189,7 @@ app.get('/user/:id', function (req, res) {
try {
res.send(req.params.id);
} catch(err) {
res.send(err); // OK (the above `res.send()` is already reported by js/xss)
res.send(err); // OK - (the above `res.send()` is already reported by js/xss)
}
});
@@ -210,7 +210,7 @@ var fs = require("fs");
log.info(foo);
localStorage.setItem(foo);
} catch (e) {
$('myId').html(e); // OK
$('myId').html(e);
}
})();

View File

@@ -4,8 +4,7 @@ var app = express();
app.get('/user/:id', function(req, res) {
if (!isValidUserId(req.params.id)) {
// BAD: a request parameter is incorporated without validation into the response
res.send("Unknown user: " + req.params.id);
res.send("Unknown user: " + req.params.id); // $ Alert - a request parameter is incorporated without validation into the response
moreBadStuff(req.params, res);
} else {
// TODO: do something exciting
@@ -14,32 +13,32 @@ app.get('/user/:id', function(req, res) {
});
function moreBadStuff(params, res) {
res.send("Unknown user: " + params.id); // NOT OK
res.send("Unknown user: " + params.id); // $ Alert
}
var marked = require("marked");
app.get('/user/:id', function(req, res) {
res.send(req.body); // NOT OK
res.send(marked(req.body)); // NOT OK
res.send(req.body); // $ Alert
res.send(marked(req.body)); // $ Alert
});
var table = require('markdown-table')
app.get('/user/:id', function(req, res) {
res.send(req.body); // NOT OK
res.send(req.body); // $ Alert
var mytable = table([
['Name', 'Content'],
['body', req.body]
]);
res.send(mytable); // NOT OK - FIXME: only works in OLD dataflow, add implicit reads before library-contributed taint steps
res.send(mytable); // $ Alert - FIXME: only works in OLD dataflow, add implicit reads before library-contributed taint steps
});
var showdown = require('showdown');
var converter = new showdown.Converter();
app.get('/user/:id', function(req, res) {
res.send(req.body); // NOT OK
res.send(converter.makeHtml(req.body)); // NOT OK
res.send(req.body); // $ Alert
res.send(converter.makeHtml(req.body)); // $ Alert
});
var unified = require('unified');
@@ -53,7 +52,7 @@ var sanitize = require("rehype-sanitize");
const { resetExtensions } = require('showdown');
app.get('/user/:id', function (req, res) {
res.send(req.body); // NOT OK
res.send(req.body); // $ Alert
unified()
.use(markdown)
@@ -62,17 +61,17 @@ app.get('/user/:id', function (req, res) {
.use(format)
.use(html)
.process(req.body, function (err, file) {
res.send(file); // NOT OK
res.send(file); // $ Alert
});
res.send(remark().processSync(req.body).toString()); // NOT OK
res.send(remark().processSync(req.body).toString()); // $ Alert
res.send(remark().use(sanitize).processSync(req.body).toString()); // OK
res.send(remark().use(sanitize).processSync(req.body).toString());
res.send(unified().use(markdown).processSync(req.body).toString); // NOT OK
res.send(unified().use(markdown).processSync(req.body).toString); // $ Alert
remark().process(req.body, (e, f) => {
res.send(f); // NOT OK
res.send(f); // $ Alert
})
});
@@ -80,9 +79,9 @@ import snarkdown from 'snarkdown';
var snarkdown2 = require("snarkdown");
app.get('/user/:id', function (req, res) {
res.send(req.body); // NOT OK
res.send(snarkdown(req.body)); // NOT OK
res.send(snarkdown2(req.body)); // NOT OK
res.send(req.body); // $ Alert
res.send(snarkdown(req.body)); // $ Alert
res.send(snarkdown2(req.body)); // $ Alert
});
const markdownIt = require('markdown-it')({
@@ -94,20 +93,20 @@ const markdownIt3 = require('markdown-it')({html: true})
.use(require('markdown-it-highlightjs'));
app.get('/user/:id', function (req, res) {
res.send(req.body); // NOT OK
res.send(markdownIt.render(req.body)); // NOT OK
res.send(req.body); // $ Alert
res.send(markdownIt.render(req.body)); // $ Alert
res.send(markdownIt2.render(req.body)); // OK - no html
res.send(markdownIt3.render(req.body)); // NOT OK
res.send(markdownIt3.render(req.body)); // $ Alert
res.send(markdownIt.use(require('markdown-it-sanitizer')).render(req.body)); // OK - HTML is sanitized.
res.send(markdownIt.use(require('markdown-it-abbr')).use(unknown).render(req.body)); // NOT OK
res.send(markdownIt.use(require('markdown-it-sanitizer')).render(req.body)); // OK - HTML is sanitized.
res.send(markdownIt.use(require('markdown-it-abbr')).use(unknown).render(req.body)); // $ Alert
});
var Hapi = require('hapi');
var hapi = new Hapi.Server();
hapi.route({
handler: function (request){
return request.query.p; // NOT OK
return request.query.p; // $ Alert
}});
app.get("invalid/keys/:id", async (req, res) => {

View File

@@ -7,7 +7,7 @@ app.get('/user/:id', function (req, res) {
res.send("FOO: " + req.params.id); // OK - content type is plain text
} else {
res.set('Content-Type', 'text/html');
res.send("FOO: " + req.params.id); // NOT OK - content type is HTML.
res.send("FOO: " + req.params.id); // $ Alert - content type is HTML.
}
});
@@ -17,7 +17,7 @@ app.get('/user/:id', function (req, res) {
res.send("FOO: " + req.params.id); // OK - content type is JSON
} else {
res.writeHead(404);
res.send("FOO: " + req.params.id); // NOT OK - content type is not set.
res.send("FOO: " + req.params.id); // $ Alert - content type is not set.
}
});
@@ -36,10 +36,10 @@ app.get('/user/:id', function (req, res) {
app.get('/user/:id', function (req, res) {
if (err) {
res.statusCode = 404;
res.end("FOO: " + req.params.id); // NOT OK
res.end("FOO: " + req.params.id); // $ Alert
} else {
res.setHeader('Content-Type', 'text/plain;charset=utf8');
res.end("FOO: " + req.params.id); // OK
res.end("FOO: " + req.params.id);
}
});
@@ -50,10 +50,10 @@ function textContentType() {
app.get('/user/:id', function (req, res) {
if (err) {
res.header({'Content-Type': textContentType()});
res.end("FOO: " + req.params.id); // OK
res.end("FOO: " + req.params.id);
} else {
res.setHeader('Content-Type', 'text/plain;charset=utf8');
res.end("FOO: " + req.params.id); // OK
res.end("FOO: " + req.params.id);
}
});
@@ -67,13 +67,13 @@ app.get('/user/:id', function (req, res) {
somethingMore();
while(Math.random()) {};
res.writeHead(404);
res.send("FOO: " + req.params.id); // NOT OK - content type is not set.
res.send("FOO: " + req.params.id); // $ Alert - content type is not set.
});
app.get('/user/:id', function (req, res) {
res.header({'Content-Type': textContentType()});
myFancyFunction(() => {
res.send("FOO: " + req.params.id); // OK
res.send("FOO: " + req.params.id);
});
res.end("FOO: " + req.params.id); // OK
res.end("FOO: " + req.params.id);
});

View File

@@ -5,7 +5,7 @@ var app = express();
app.get('/user/:id', function(req, res) {
if (!isValidUserId(req.params.id))
// GOOD: request parameter is sanitized before incorporating it into the response
// OK - request parameter is sanitized before incorporating it into the response
res.send("Unknown user: " + escape(req.params.id));
else
// TODO: do something exciting
@@ -15,13 +15,13 @@ app.get('/user/:id', function(req, res) {
app.get('/user/:id', function(req, res) {
if (!isValidUserId(req.params.id))
// GOOD: templating prevents XSS
// OK - templating prevents XSS
res.render(invalidUserIdTemplate, { id: req.params.id });
});
app.get('/user/:id', function(req, res) {
if (!isValidUserId(req.params.id)) {
// GOOD: response content type set to text
// OK - response content type set to text
res.set('Content-Type', 'text/plain');
res.send("Unknown user: " + req.params.id);
} else
@@ -35,7 +35,7 @@ function textContentType() {
app.get('/user/:id', function(req, res) {
if (!isValidUserId(req.params.id)) {
// GOOD: response content type set to text
// OK - response content type set to text
res.set('Content-Type', textContentType());
res.send("Unknown user: " + req.params.id);
} else
@@ -53,7 +53,7 @@ app.get('/echo', function(req, res) {
app.get('/user/:id', function(req, res) {
const url = req.params.id;
if (!/["'&<>]/.exec(url)) {
res.send(url); // OK
res.send(url);
}
});
@@ -66,7 +66,7 @@ function escapeHtml1 (str) {
app.get('/user/:id', function(req, res) {
const url = req.params.id;
res.send(escapeHtml1(url)); // OK
res.send(escapeHtml1(url));
});
const matchHtmlRegExp = /["'&<>]/;
@@ -82,6 +82,6 @@ function escapeHtml2 (string) {
app.get('/user/:id', function(req, res) {
const url = req.params.id;
res.send(escapeHtml2(url)); // OK
res.send(escapeHtml2(url));
});

View File

@@ -134,9 +134,9 @@ function escapeHtml4(s) {
app.get('/user/:id', function (req, res) {
const url = req.params.id;
res.send(escapeHtml1(url)); // OK
res.send(escapeHtml2(url)); // OK
res.send(escapeHtml3(url)); // OK - but FP [INCONSISTENCY]
res.send(escapeHtml4(url)); // OK
res.send(escapeHtml1(url));
res.send(escapeHtml2(url));
res.send(escapeHtml3(url)); // $ SPURIOUS: Alert - FP
res.send(escapeHtml4(url));
});

View File

@@ -5,6 +5,6 @@ var app = express();
app.use(cookieParser());
app.get('/cookie/:name', function(req, res) {
// OK
res.send("Here, have a cookie: " + req.cookies[req.params.name]);
});

View File

@@ -2,7 +2,7 @@ var express = require('express');
express().get('/user/', function(req, res) {
var evil = req.query.evil;
res.send(console.log("<div>%s</div>", evil)); // OK (returns undefined)
res.send(util.format("<div>%s</div>", evil)); // NOT OK
res.send(require("printf")("<div>%s</div>", evil)); // NOT OK
res.send(console.log("<div>%s</div>", evil)); // OK - returns undefined
res.send(util.format("<div>%s</div>", evil)); // $ Alert
res.send(require("printf")("<div>%s</div>", evil)); // $ Alert
});

View File

@@ -3,13 +3,13 @@ var liveServer = require("live-server");
const middleware = [function(req, res, next) {
const tainted = req.url;
res.end(`<html><body>${tainted}</body></html>`); // NOT OK
res.end(`<html><body>${tainted}</body></html>`); // $ Alert
}];
middleware.push(function(req, res, next) {
const tainted = req.url;
res.end(`<html><body>${tainted}</body></html>`); // NOT OK
res.end(`<html><body>${tainted}</body></html>`); // $ Alert
});
var params = {

View File

@@ -7,7 +7,7 @@ let app = express();
app.get("/some/path", (req, res) => {
function sendResponse(x, y) {
res.send(x + y); // NOT OK
res.send(x + y); // $ Alert
}
let callback = sendResponse.bind(null, req.url);
@@ -16,7 +16,7 @@ app.get("/some/path", (req, res) => {
app.get("/underscore", (req, res) => {
function sendResponse(x, y) {
res.send(x + y); // NOT OK
res.send(x + y); // $ Alert
}
let callback = underscore.partial(sendResponse, req.url);
@@ -25,7 +25,7 @@ app.get("/underscore", (req, res) => {
app.get("/lodash", (req, res) => {
function sendResponse(x, y) {
res.send(x + y); // NOT OK
res.send(x + y); // $ Alert
}
let callback = lodash.partial(sendResponse, req.url);
@@ -34,7 +34,7 @@ app.get("/lodash", (req, res) => {
app.get("/ramda", (req, res) => {
function sendResponse(x, y) {
res.send(x + y); // NOT OK
res.send(x + y); // $ Alert
}
let callback = R.partial(sendResponse, [req.url]);
@@ -49,7 +49,7 @@ app.get("/return", (req, res) => {
let callback = getFirst.bind(null, req.url);
res.send(callback); // OK - the callback itself is not tainted
res.send(callback()); // NOT OK - but not currently detected [INCONSISTENCY]
res.send(callback()); // $ MISSING: Alert - not currently detected
res.send(getFirst("Hello")); // OK - argument is not tainted from this call site
});

View File

@@ -3,9 +3,9 @@ let app = express();
app.get("/some/path", (req, res) => {
new Promise((resolve, reject) => resolve(req.query.data))
.then(x => res.send(x)); // NOT OK
.then(x => res.send(x)); // $ Alert
new Promise((resolve, reject) => resolve(req.query.data))
.then(x => escapeHtml(x))
.then(x => res.send(x)); // OK
.then(x => res.send(x));
});

View File

@@ -4,8 +4,8 @@ var app = express();
app.get('/user/:id', function(req, res) {
let { p, q: r } = req.params;
res.send(p); // NOT OK
res.send(r); // NOT OK
res.send(p); // $ Alert
res.send(r); // $ Alert
});
const aKnownValue = "foo";
@@ -14,13 +14,13 @@ app.get('/bar', function(req, res) {
let { p } = req.params;
if (p == aKnownValue)
res.send(p); // OK
res.send(p); // NOT OK
res.send(p);
res.send(p); // $ Alert
if (p != aKnownValue)
res.send(p); // NOT OK
res.send(p); // $ Alert
else
res.send(p); // OK
res.send(p);
});
@@ -33,8 +33,8 @@ app.get('/baz', function(req, res) {
obj.p = p;
var other = clone(obj);
res.send(p); // NOT OK
res.send(other.p); // NOT OK
res.send(p); // $ Alert
res.send(other.p); // $ Alert
});
const serializeJavaScript = require('serialize-javascript');
@@ -44,11 +44,11 @@ app.get('/baz', function(req, res) {
var serialized = serializeJavaScript(p);
res.send(serialized); // OK
res.send(serialized);
var unsafe = serializeJavaScript(p, {unsafe: true});
res.send(unsafe); // NOT OK
res.send(unsafe); // $ Alert
});
const fclone = require('fclone');
@@ -60,8 +60,8 @@ app.get('/baz', function(req, res) {
obj.p = p;
var other = fclone(obj);
res.send(p); // NOT OK
res.send(other.p); // NOT OK
res.send(p); // $ Alert
res.send(other.p); // $ Alert
});
const jc = require('json-cycle');
@@ -72,8 +72,8 @@ app.get('/baz', function(req, res) {
obj.p = p;
var other = jc.retrocycle(jc.decycle(obj));
res.send(p); // NOT OK
res.send(other.p); // NOT OK
res.send(p); // $ Alert
res.send(other.p); // $ Alert
});
const sortKeys = require('sort-keys');
@@ -85,6 +85,6 @@ app.get('/baz', function(req, res) {
obj.p = p;
var other = sortKeys(obj);
res.send(p); // NOT OK
res.send(other.p); // NOT OK
res.send(p); // $ Alert
res.send(other.p); // $ Alert
});

View File

@@ -3,11 +3,11 @@ var express = require('express');
var app = express();
app.enable('x-powered-by').disable('x-powered-by').get('/', function (req, res) {
let { p } = req.params;
res.send(p); // NOT OK
res.send(p); // $ Alert
});
const prettier = require("prettier");
app.post("foobar", function (reg, res) {
const code = prettier.format(reg.body, { semi: false, parser: "babel" });
res.send(code); // NOT OK
res.send(code); // $ Alert
});

View File

@@ -5,7 +5,7 @@ var express = require('express');
express().get('/', function(req, res) {
fs.readdir("/myDir", function (error, files1) {
res.send(files1); // NOT OK
res.send(files1); // $ Alert
});
});
@@ -23,18 +23,18 @@ http.createServer(function (req, res) {
}
fs.readdir("/myDir", function (error, files1) {
res.write(files1); // NOT OK
res.write(files1); // $ Alert
var dirs = [];
var files2 = [];
files1.forEach(function (file) {
files2.push(file);
});
res.write(files2); // NOT OK
res.write(files2); // $ Alert
var files3 = format(files2);
res.write(files3); // NOT OK
res.write(files3); // $ Alert
});
});

Some files were not shown because too many files have changed in this diff Show More