Merge master into next.

Conflict in `cpp/ql/test/library-tests/sideEffects/functions/sideEffects.expected`,
resolved by accepting test output (combining changes).
This commit is contained in:
Aditya Sharad
2018-12-12 17:22:16 +00:00
345 changed files with 9800 additions and 2436 deletions

View File

@@ -0,0 +1,13 @@
| tst-IncompleteUrlSubstringSanitization.js:4:5:4:27 | x.index ... e.com") | '$@' may be at an arbitrary position in the sanitized URL. | tst-IncompleteUrlSubstringSanitization.js:4:15:4:26 | "secure.com" | secure.com |
| tst-IncompleteUrlSubstringSanitization.js:5:5:5:27 | x.index ... e.net") | '$@' may be at an arbitrary position in the sanitized URL. | tst-IncompleteUrlSubstringSanitization.js:5:15:5:26 | "secure.net" | secure.net |
| tst-IncompleteUrlSubstringSanitization.js:6:5:6:28 | x.index ... e.com") | '$@' may be at an arbitrary position in the sanitized URL. | tst-IncompleteUrlSubstringSanitization.js:6:15:6:27 | ".secure.com" | .secure.com |
| tst-IncompleteUrlSubstringSanitization.js:10:5:10:27 | x.index ... e.com") | '$@' may be at an arbitrary position in the sanitized URL. | tst-IncompleteUrlSubstringSanitization.js:10:15:10:26 | "secure.com" | secure.com |
| tst-IncompleteUrlSubstringSanitization.js:11:5:11:27 | x.index ... e.com") | '$@' may be at an arbitrary position in the sanitized URL. | tst-IncompleteUrlSubstringSanitization.js:11:15:11:26 | "secure.com" | secure.com |
| tst-IncompleteUrlSubstringSanitization.js:12:5:12:27 | x.index ... e.com") | '$@' may be at an arbitrary position in the sanitized URL. | tst-IncompleteUrlSubstringSanitization.js:12:15:12:26 | "secure.com" | secure.com |
| tst-IncompleteUrlSubstringSanitization.js:14:5:14:38 | x.start ... e.com") | '$@' may be at an arbitrary position in the sanitized URL. | tst-IncompleteUrlSubstringSanitization.js:14:18:14:37 | "https://secure.com" | https://secure.com |
| tst-IncompleteUrlSubstringSanitization.js:15:5:15:28 | x.endsW ... e.com") | '$@' may be at an arbitrary position in the sanitized URL. | tst-IncompleteUrlSubstringSanitization.js:15:16:15:27 | "secure.com" | secure.com |
| tst-IncompleteUrlSubstringSanitization.js:20:5:20:28 | x.inclu ... e.com") | '$@' may be at an arbitrary position in the sanitized URL. | tst-IncompleteUrlSubstringSanitization.js:20:16:20:27 | "secure.com" | secure.com |
| tst-IncompleteUrlSubstringSanitization.js:32:5:32:35 | x.index ... e.com") | '$@' may be at an arbitrary position in the sanitized URL. | tst-IncompleteUrlSubstringSanitization.js:32:15:32:34 | "https://secure.com" | https://secure.com |
| tst-IncompleteUrlSubstringSanitization.js:33:5:33:39 | x.index ... m:443") | '$@' may be at an arbitrary position in the sanitized URL. | tst-IncompleteUrlSubstringSanitization.js:33:15:33:38 | "https: ... om:443" | https://secure.com:443 |
| tst-IncompleteUrlSubstringSanitization.js:34:5:34:36 | x.index ... .com/") | '$@' may be at an arbitrary position in the sanitized URL. | tst-IncompleteUrlSubstringSanitization.js:34:15:34:35 | "https: ... e.com/" | https://secure.com/ |
| tst-IncompleteUrlSubstringSanitization.js:52:5:52:41 | x.index ... ernal") | '$@' may be at an arbitrary position in the sanitized URL. | tst-IncompleteUrlSubstringSanitization.js:52:15:52:40 | "https: ... ternal" | https://example.internal |

View File

@@ -0,0 +1 @@
Security/CWE-020/IncompleteUrlSubstringSanitization.ql

View File

@@ -0,0 +1,10 @@
| examples/IncorrectSuffixCheck.js:2:10:2:49 | x.lastI ... .length | This suffix check is missing a length comparison to correctly handle lastIndexOf returning -1. |
| tst.js:2:10:2:45 | x.index ... .length | This suffix check is missing a length comparison to correctly handle indexOf returning -1. |
| tst.js:9:10:9:55 | x.index ... gth - 1 | This suffix check is missing a length comparison to correctly handle indexOf returning -1. |
| tst.js:17:10:17:31 | x.index ... = delta | This suffix check is missing a length comparison to correctly handle indexOf returning -1. |
| tst.js:25:10:25:69 | x.index ... .length | This suffix check is missing a length comparison to correctly handle indexOf returning -1. |
| tst.js:32:10:32:51 | x.index ... th - 11 | This suffix check is missing a length comparison to correctly handle indexOf returning -1. |
| tst.js:39:10:39:49 | x.lastI ... .length | This suffix check is missing a length comparison to correctly handle lastIndexOf returning -1. |
| tst.js:55:32:55:71 | x.index ... gth - 1 | This suffix check is missing a length comparison to correctly handle indexOf returning -1. |
| tst.js:67:32:67:71 | x.index ... gth - 1 | This suffix check is missing a length comparison to correctly handle indexOf returning -1. |
| tst.js:76:25:76:57 | index = ... gth - 1 | This suffix check is missing a length comparison to correctly handle indexOf returning -1. |

View File

@@ -0,0 +1 @@
Security/CWE-020/IncorrectSuffixCheck.ql

View File

@@ -0,0 +1,3 @@
function endsWith(x, y) {
return x.lastIndexOf(y) === x.length - y.length;
}

View File

@@ -0,0 +1,4 @@
function endsWith(x, y) {
let index = x.lastIndexOf(y);
return index !== -1 && index === x.length - y.length;
}

View File

@@ -0,0 +1,54 @@
(function(x){
x.indexOf("internal"); // NOT OK, but not flagged
x.indexOf("localhost"); // NOT OK, but not flagged
x.indexOf("secure.com"); // NOT OK
x.indexOf("secure.net"); // NOT OK
x.indexOf(".secure.com"); // NOT OK
x.indexOf("sub.secure."); // NOT OK, but not flagged
x.indexOf(".sub.secure."); // NOT OK, but not flagged
x.indexOf("secure.com") === -1; // NOT OK
x.indexOf("secure.com") === 0; // NOT OK
x.indexOf("secure.com") >= 0; // NOT OK
x.startsWith("https://secure.com"); // NOT OK
x.endsWith("secure.com"); // NOT OK
x.endsWith(".secure.com"); // OK
x.startsWith("secure.com/"); // OK
x.indexOf("secure.com/") === 0; // OK
x.includes("secure.com"); // NOT OK
x.indexOf("#"); // OK
x.indexOf(":"); // OK
x.indexOf(":/"); // OK
x.indexOf("://"); // OK
x.indexOf("//"); // OK
x.indexOf(":443"); // OK
x.indexOf("/some/path/"); // OK
x.indexOf("some/path"); // OK
x.indexOf("/index.html"); // OK
x.indexOf(":template:"); // OK
x.indexOf("https://secure.com"); // NOT OK
x.indexOf("https://secure.com:443"); // NOT OK
x.indexOf("https://secure.com/"); // NOT OK
x.indexOf(".cn"); // NOT OK, but not flagged
x.indexOf(".jpg"); // OK
x.indexOf("index.html"); // OK
x.indexOf("index.js"); // OK
x.indexOf("index.php"); // OK
x.indexOf("index.css"); // OK
x.indexOf("secure=true"); // OK (query param)
x.indexOf("&auth="); // OK (query param)
x.indexOf(getCurrentDomain()); // NOT OK, but not flagged
x.indexOf(location.origin); // NOT OK, but not flagged
x.indexOf("tar.gz") + offset // OK
x.indexOf("tar.gz") - offset // OK
x.indexOf("https://example.internal"); // NOT OK
x.indexOf("https://"); // OK
});

View File

@@ -0,0 +1,77 @@
function endsWith(x, y) {
return x.indexOf(y) === x.length - y.length; // NOT OK
}
function endsWithGood(x, y) {
return x.length >= y.length && x.indexOf(y) === x.length - y.length; // OK
}
function withStringConcat(x, y) {
return x.indexOf("/" + y) === x.length - y.length - 1; // NOT OK
}
function withStringConcatGood(x, y) {
return x.length > y.length && x.indexOf("/" + y) === x.length - y.length - 1; // OK
}
function withDelta(x, y) {
let delta = x.length - y.length;
return x.indexOf(y) === delta; // NOT OK
}
function withDeltaGood(x, y) {
let delta = x.length - y.length;
return delta >= 0 && x.indexOf(y) === delta; // OK
}
function literal(x) {
return x.indexOf("example.com") === x.length - "example.com".length; // NOT OK
}
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
}
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
}
function lastIndexOfGood(x, y) {
return x.length >= y.length && x.lastIndexOf(y) === x.length - y.length; // OK
}
function withIndexOfCheckGood(x, y) {
let index = x.indexOf(y);
return index !== -1 && index === x.length - y.length - 1; // OK
}
function indexOfCheckEquality(x, y) {
return x.indexOf(y) !== -1 && x.indexOf(y) === x.length - y.length - 1; // OK
}
function indexOfCheckEqualityBad(x, y) {
return x.indexOf(y) !== 0 && x.indexOf(y) === x.length - y.length - 1; // NOT OK
}
function indexOfCheckGood(x, y) {
return x.indexOf(y) >= 0 && x.indexOf(y) === x.length - y.length - 1; // OK
}
function indexOfCheckGoodSharp(x, y) {
return x.indexOf(y) > -1 && x.indexOf(y) === x.length - y.length - 1; // OK
}
function indexOfCheckBad(x, y) {
return x.indexOf(y) >= -1 && x.indexOf(y) === x.length - y.length - 1; // NOT OK
}
function endsWithSlash(x) {
return x.indexOf("/") === x.length - 1; // OK - even though it also matches the empty string
}
function withIndexOfCheckBad(x, y) {
let index = x.indexOf(y);
return index !== 0 && index === x.length - y.length - 1; // NOT OK
}

View File

@@ -205,6 +205,12 @@ nodes
| tst.js:244:39:244:55 | props.propTainted |
| tst.js:248:60:248:82 | this.st ... Tainted |
| tst.js:252:23:252:29 | tainted |
| winjs.js:2:7:2:53 | tainted |
| winjs.js:2:17:2:33 | document.location |
| winjs.js:2:17:2:40 | documen ... .search |
| winjs.js:2:17:2:53 | documen ... ring(1) |
| winjs.js:3:43:3:49 | tainted |
| winjs.js:4:43:4:49 | tainted |
| xss-through-filenames.js:7:43:7:48 | files1 |
| xss-through-filenames.js:8:18:8:23 | files1 |
| xss-through-filenames.js:25:43:25:48 | files1 |
@@ -377,6 +383,11 @@ edges
| tst.js:238:23:238:29 | tainted | tst.js:228:32:228:49 | prevProps.tainted4 |
| tst.js:244:39:244:55 | props.propTainted | tst.js:248:60:248:82 | this.st ... Tainted |
| tst.js:252:23:252:29 | tainted | tst.js:244:39:244:55 | props.propTainted |
| winjs.js:2:7:2:53 | tainted | winjs.js:3:43:3:49 | tainted |
| winjs.js:2:7:2:53 | tainted | winjs.js:4:43:4:49 | tainted |
| winjs.js:2:17:2:33 | document.location | winjs.js:2:17:2:40 | documen ... .search |
| winjs.js:2:17:2:40 | documen ... .search | winjs.js:2:17:2:53 | documen ... ring(1) |
| winjs.js:2:17:2:53 | documen ... ring(1) | winjs.js:2:7:2:53 | tainted |
| xss-through-filenames.js:7:43:7:48 | files1 | xss-through-filenames.js:8:18:8:23 | files1 |
| xss-through-filenames.js:25:43:25:48 | files1 | xss-through-filenames.js:26:19:26:24 | files1 |
| xss-through-filenames.js:25:43:25:48 | files1 | xss-through-filenames.js:30:34:30:37 | file |

View File

@@ -162,6 +162,12 @@ nodes
| tst.js:244:39:244:55 | props.propTainted |
| tst.js:248:60:248:82 | this.st ... Tainted |
| tst.js:252:23:252:29 | tainted |
| winjs.js:2:7:2:53 | tainted |
| winjs.js:2:17:2:33 | document.location |
| winjs.js:2:17:2:40 | documen ... .search |
| winjs.js:2:17:2:53 | documen ... ring(1) |
| winjs.js:3:43:3:49 | tainted |
| winjs.js:4:43:4:49 | tainted |
edges
| addEventListener.js:1:43:1:47 | event | addEventListener.js:2:20:2:24 | event |
| addEventListener.js:2:20:2:24 | event | addEventListener.js:2:20:2:29 | event.data |
@@ -288,6 +294,11 @@ edges
| tst.js:238:23:238:29 | tainted | tst.js:228:32:228:49 | prevProps.tainted4 |
| tst.js:244:39:244:55 | props.propTainted | tst.js:248:60:248:82 | this.st ... Tainted |
| tst.js:252:23:252:29 | tainted | tst.js:244:39:244:55 | props.propTainted |
| winjs.js:2:7:2:53 | tainted | winjs.js:3:43:3:49 | tainted |
| winjs.js:2:7:2:53 | tainted | winjs.js:4:43:4:49 | tainted |
| winjs.js:2:17:2:33 | document.location | winjs.js:2:17:2:40 | documen ... .search |
| winjs.js:2:17:2:40 | documen ... .search | winjs.js:2:17:2:53 | documen ... ring(1) |
| winjs.js:2:17:2:53 | documen ... ring(1) | winjs.js:2:7:2:53 | tainted |
#select
| addEventListener.js:2:20:2:29 | event.data | addEventListener.js:1:43:1:47 | event | addEventListener.js:2:20:2:29 | event.data | Cross-site scripting vulnerability due to $@. | addEventListener.js:1:43:1:47 | event | user-provided value |
| jquery.js:4:5:4:11 | tainted | jquery.js:2:17:2:33 | document.location | jquery.js:4:5:4:11 | tainted | Cross-site scripting vulnerability due to $@. | jquery.js:2:17:2:33 | document.location | user-provided value |
@@ -349,3 +360,5 @@ edges
| tst.js:224:28:224:46 | this.props.tainted3 | tst.js:194:19:194:35 | document.location | tst.js:224:28:224:46 | this.props.tainted3 | Cross-site scripting vulnerability due to $@. | tst.js:194:19:194:35 | document.location | user-provided value |
| tst.js:228:32:228:49 | prevProps.tainted4 | tst.js:194:19:194:35 | document.location | tst.js:228:32:228:49 | prevProps.tainted4 | Cross-site scripting vulnerability due to $@. | tst.js:194:19:194:35 | document.location | user-provided value |
| tst.js:248:60:248:82 | this.st ... Tainted | tst.js:194:19:194:35 | document.location | tst.js:248:60:248:82 | this.st ... Tainted | Cross-site scripting vulnerability due to $@. | tst.js:194:19:194:35 | document.location | user-provided value |
| winjs.js:3:43:3:49 | tainted | winjs.js:2:17:2:33 | document.location | winjs.js:3:43:3:49 | tainted | Cross-site scripting vulnerability due to $@. | winjs.js:2:17:2:33 | document.location | user-provided value |
| winjs.js:4:43:4:49 | tainted | winjs.js:2:17:2:33 | document.location | winjs.js:4:43:4:49 | tainted | Cross-site scripting vulnerability due to $@. | winjs.js:2:17:2:33 | document.location | user-provided value |

View File

@@ -0,0 +1,5 @@
function test(elt) {
var tainted = document.location.search.substring(1);
WinJS.Utilities.setInnerHTMLUnsafe(elt, tainted);
WinJS.Utilities.setOuterHTMLUnsafe(elt, tainted);
}

View File

@@ -0,0 +1,6 @@
| tst.js:2:10:4:33 | s.repla ... &") | This replacement may double-escape '&' characters from $@. | tst.js:2:10:3:34 | s.repla ... apos;") | here |
| tst.js:20:10:20:33 | s.repla ... g, "&") | This replacement may produce '&' characters that are double-unescaped $@. | tst.js:20:10:21:35 | s.repla ... , "\\"") | here |
| tst.js:30:10:30:33 | s.repla ... g, "&") | This replacement may produce '&' characters that are double-unescaped $@. | tst.js:30:10:32:34 | s.repla ... g, "'") | here |
| tst.js:47:7:47:30 | s.repla ... g, "&") | This replacement may produce '&' characters that are double-unescaped $@. | tst.js:48:7:48:32 | s.repla ... , "\\"") | here |
| tst.js:53:10:53:33 | s.repla ... , '\\\\') | This replacement may produce '\\' characters that are double-unescaped $@. | tst.js:53:10:54:33 | s.repla ... , '\\'') | here |
| tst.js:60:7:60:28 | s.repla ... '%25') | This replacement may double-escape '%' characters from $@. | tst.js:59:7:59:28 | s.repla ... '%26') | here |

View File

@@ -0,0 +1 @@
Security/CWE-116/DoubleEscaping.ql

View File

@@ -0,0 +1,62 @@
function badEncode(s) {
return s.replace(/"/g, """)
.replace(/'/g, "'")
.replace(/&/g, "&");
}
function goodEncode(s) {
return s.replace(/&/g, "&")
.replace(/"/g, """)
.replace(/'/g, "'");
}
function goodDecode(s) {
return s.replace(/"/g, "\"")
.replace(/'/g, "'")
.replace(/&/g, "&");
}
function badDecode(s) {
return s.replace(/&/g, "&")
.replace(/"/g, "\"")
.replace(/'/g, "'");
}
function cleverEncode(code) {
return code.replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/&(?![\w\#]+;)/g, '&amp;');
}
function badDecode2(s) {
return s.replace(/&amp;/g, "&")
.replace(/s?ome|thin*g/g, "else")
.replace(/&apos;/g, "'");
}
function goodDecodeInLoop(ss) {
var res = [];
for (var s of ss) {
s = s.replace(/&quot;/g, "\"")
.replace(/&apos;/g, "'")
.replace(/&amp;/g, "&");
res.push(s);
}
return res;
}
function badDecode3(s) {
s = s.replace(/&amp;/g, "&");
s = s.replace(/&quot;/g, "\"");
return s.replace(/&apos;/g, "'");
}
function badUnescape(s) {
return s.replace(/\\\\/g, '\\')
.replace(/\\'/g, '\'')
.replace(/\\"/g, '\"');
}
function badPercentEscape(s) {
s = s.replace(/&/g, '%26');
s = s.replace(/%/g, '%25');
return s;
}