'); // OK
- // NOT OK
let params = (new URL(document.location)).searchParams;
- $('name').html(params.get('name'));
+ $('name').html(params.get('name')); // NOT OK
- // NOT OK
var searchParams = new URLSearchParams(target.substring(1));
- $('name').html(searchParams.get('name'));
+ $('name').html(searchParams.get('name')); // NOT OK
}
function foo(target) {
@@ -331,14 +328,11 @@ function getTaintedUrl() {
}
function URLPseudoProperties() {
- // NOT OK
let params = getTaintedUrl().searchParams;
- $('name').html(params.get('name'));
+ $('name').html(params.get('name')); // NOT OK
- // OK (.get is not defined on a URL)
let myUrl = getTaintedUrl();
- $('name').html(myUrl.get('name'));
-
+ $('name').html(myUrl.get('name')); // OK (.get is not defined on a URL)
}
diff --git a/javascript/ql/test/query-tests/Security/CWE-079/typeahead.js b/javascript/ql/test/query-tests/Security/CWE-079/typeahead.js
index a7271a08135f..c57b4e64ebb0 100644
--- a/javascript/ql/test/query-tests/Security/CWE-079/typeahead.js
+++ b/javascript/ql/test/query-tests/Security/CWE-079/typeahead.js
@@ -7,7 +7,7 @@
source: autocompleter.ttAdapter(),
templates: {
suggestion: function(loc) {
- return loc; // NOT OK!
+ return loc; // NOT OK! - but not flagged due to not connecting the Bloodhound source with this sink [INCONSISTENCY]
}
}
})
diff --git a/javascript/ql/test/query-tests/Security/CWE-079/unsafe-jquery-plugin.js b/javascript/ql/test/query-tests/Security/CWE-079/unsafe-jquery-plugin.js
index ac544d5d3290..78ed6a7d9f50 100644
--- a/javascript/ql/test/query-tests/Security/CWE-079/unsafe-jquery-plugin.js
+++ b/javascript/ql/test/query-tests/Security/CWE-079/unsafe-jquery-plugin.js
@@ -65,7 +65,7 @@
$.fn.my_plugin = function my_plugin(element, options) {
this.$element = $(element);
this.options = $.extend({}, options);
- if (this.options.parent) this.$parent = $(this.options.parent) // NOT OK
+ if (this.options.parent) this.$parent = $(this.options.parent) // NOT OK - but not flagged [INCONSISTENCY]
};
$.fn.my_plugin = function my_plugin(options) {
@@ -103,7 +103,7 @@
menu: '
',
target: '.my_plugin'
}, options);
- $(options.menu); // OK
+ $(options.menu); // OK - but is flagged [INCONSISTENCY]
$(options.target); // NOT OK
};
@@ -113,7 +113,7 @@
};
$.fn.my_plugin = function my_plugin(options) {
options = $.extend({}, $.fn.my_plugin.defaults, options);
- $(options.menu); // OK
+ $(options.menu); // OK - but is flagged [INCONSISTENCY]
$(options.target); // NOT OK
};
@@ -152,9 +152,9 @@
$.fn.my_plugin = function my_plugin(options) {
let target = options.target;
- target === DEFAULTS.target? $(target): $(document).find(target); // NOT OK
- options.target === DEFAULTS.target? $(options.target): $(document).find(options.target); // NOT OK
- options.targets.a === DEFAULTS.target? $(options.target.a): $(document).find(options.target.a); // OK - but still flagged
+ target === DEFAULTS.target? $(target): $(document).find(target); // OK
+ options.target === DEFAULTS.target? $(options.target): $(document).find(options.target); // OK
+ options.targets.a === DEFAULTS.target? $(options.target.a): $(document).find(options.target.a); // OK - but still flagged [INCONSISTENCY]
}
$.fn.my_plugin = function my_plugin(options) {
diff --git a/javascript/ql/test/query-tests/Security/CWE-089/untyped/Consistency.expected b/javascript/ql/test/query-tests/Security/CWE-089/untyped/Consistency.expected
new file mode 100644
index 000000000000..e69de29bb2d1
diff --git a/javascript/ql/test/query-tests/Security/CWE-089/untyped/Consistency.ql b/javascript/ql/test/query-tests/Security/CWE-089/untyped/Consistency.ql
new file mode 100644
index 000000000000..0ab292b7b820
--- /dev/null
+++ b/javascript/ql/test/query-tests/Security/CWE-089/untyped/Consistency.ql
@@ -0,0 +1,4 @@
+import javascript
+import testUtilities.ConsistencyChecking
+import semmle.javascript.security.dataflow.SqlInjection
+import semmle.javascript.security.dataflow.NosqlInjection
diff --git a/javascript/ql/test/query-tests/Security/CWE-089/untyped/DatabaseAccesses.expected b/javascript/ql/test/query-tests/Security/CWE-089/untyped/DatabaseAccesses.expected
index 1e5ddde14ec3..3191d16884fb 100644
--- a/javascript/ql/test/query-tests/Security/CWE-089/untyped/DatabaseAccesses.expected
+++ b/javascript/ql/test/query-tests/Security/CWE-089/untyped/DatabaseAccesses.expected
@@ -16,24 +16,24 @@
| mongoose.js:63:2:63:34 | Documen ... then(X) |
| mongoose.js:65:2:65:51 | Documen ... on(){}) |
| mongoose.js:67:2:68:27 | new Mon ... on(){}) |
-| mongoose.js:71:2:77:9 | Documen ... .exec() |
-| mongoose.js:84:2:84:52 | Documen ... query)) |
+| mongoose.js:71:5:78:9 | Documen ... .exec() |
| mongoose.js:85:2:85:52 | Documen ... query)) |
-| mongoose.js:86:2:86:57 | Documen ... query)) |
+| mongoose.js:86:2:86:52 | Documen ... query)) |
| mongoose.js:87:2:87:57 | Documen ... query)) |
-| mongoose.js:88:2:88:52 | Documen ... query)) |
-| mongoose.js:89:2:89:55 | Documen ... query)) |
-| mongoose.js:91:2:91:52 | Documen ... query)) |
-| mongoose.js:92:2:92:49 | Documen ... query)) |
-| mongoose.js:93:2:93:57 | Documen ... query)) |
-| mongoose.js:94:2:94:54 | Documen ... query)) |
-| mongoose.js:95:2:95:52 | Documen ... query)) |
+| mongoose.js:88:2:88:57 | Documen ... query)) |
+| mongoose.js:89:2:89:52 | Documen ... query)) |
+| mongoose.js:90:2:90:55 | Documen ... query)) |
+| mongoose.js:92:2:92:52 | Documen ... query)) |
+| mongoose.js:93:2:93:49 | Documen ... query)) |
+| mongoose.js:94:2:94:57 | Documen ... query)) |
+| mongoose.js:95:2:95:54 | Documen ... query)) |
| mongoose.js:96:2:96:52 | Documen ... query)) |
-| mongoose.js:98:2:98:50 | Documen ... query)) |
+| mongoose.js:97:2:97:52 | Documen ... query)) |
+| mongoose.js:99:2:99:50 | Documen ... query)) |
| socketio.js:11:5:11:54 | db.run( ... ndle}`) |
| tst2.js:7:3:7:62 | sql.que ... ms.id}` |
| tst2.js:9:3:9:85 | new sql ... + "'") |
-| tst3.js:10:3:12:4 | pool.qu ... ts\\n }) |
-| tst3.js:17:3:19:4 | pool.qu ... ts\\n }) |
+| tst3.js:9:3:11:4 | pool.qu ... ts\\n }) |
+| tst3.js:16:3:18:4 | pool.qu ... ts\\n }) |
| tst4.js:8:3:8:67 | db.get( ... + '"') |
| tst.js:10:3:10:65 | db.get( ... + '"') |
diff --git a/javascript/ql/test/query-tests/Security/CWE-089/untyped/SqlInjection.expected b/javascript/ql/test/query-tests/Security/CWE-089/untyped/SqlInjection.expected
index ed8fd72141e5..c74533a2d32f 100644
--- a/javascript/ql/test/query-tests/Security/CWE-089/untyped/SqlInjection.expected
+++ b/javascript/ql/test/query-tests/Security/CWE-089/untyped/SqlInjection.expected
@@ -102,30 +102,34 @@ nodes
| mongoose.js:67:27:67:31 | query |
| mongoose.js:68:8:68:12 | query |
| mongoose.js:68:8:68:12 | query |
-| mongoose.js:72:8:72:12 | query |
-| mongoose.js:72:8:72:12 | query |
-| mongoose.js:73:7:73:11 | query |
-| mongoose.js:73:7:73:11 | query |
-| mongoose.js:74:16:74:20 | query |
-| mongoose.js:74:16:74:20 | query |
-| mongoose.js:76:10:76:14 | query |
-| mongoose.js:76:10:76:14 | query |
-| mongoose.js:81:46:81:50 | query |
-| mongoose.js:81:46:81:50 | query |
-| mongoose.js:82:47:82:51 | query |
-| mongoose.js:82:47:82:51 | query |
-| mongoose.js:84:46:84:50 | query |
-| mongoose.js:84:46:84:50 | query |
-| mongoose.js:86:51:86:55 | query |
-| mongoose.js:86:51:86:55 | query |
-| mongoose.js:88:46:88:50 | query |
-| mongoose.js:88:46:88:50 | query |
-| mongoose.js:91:46:91:50 | query |
-| mongoose.js:91:46:91:50 | query |
-| mongoose.js:93:51:93:55 | query |
-| mongoose.js:93:51:93:55 | query |
-| mongoose.js:95:46:95:50 | query |
-| mongoose.js:95:46:95:50 | query |
+| mongoose.js:71:20:71:24 | query |
+| mongoose.js:71:20:71:24 | query |
+| mongoose.js:72:16:72:20 | query |
+| mongoose.js:72:16:72:20 | query |
+| mongoose.js:73:8:73:12 | query |
+| mongoose.js:73:8:73:12 | query |
+| mongoose.js:74:7:74:11 | query |
+| mongoose.js:74:7:74:11 | query |
+| mongoose.js:75:16:75:20 | query |
+| mongoose.js:75:16:75:20 | query |
+| mongoose.js:77:10:77:14 | query |
+| mongoose.js:77:10:77:14 | query |
+| mongoose.js:82:46:82:50 | query |
+| mongoose.js:82:46:82:50 | query |
+| mongoose.js:83:47:83:51 | query |
+| mongoose.js:83:47:83:51 | query |
+| mongoose.js:85:46:85:50 | query |
+| mongoose.js:85:46:85:50 | query |
+| mongoose.js:87:51:87:55 | query |
+| mongoose.js:87:51:87:55 | query |
+| mongoose.js:89:46:89:50 | query |
+| mongoose.js:89:46:89:50 | query |
+| mongoose.js:92:46:92:50 | query |
+| mongoose.js:92:46:92:50 | query |
+| mongoose.js:94:51:94:55 | query |
+| mongoose.js:94:51:94:55 | query |
+| mongoose.js:96:46:96:50 | query |
+| mongoose.js:96:46:96:50 | query |
| mongooseJsonParse.js:19:11:19:20 | query |
| mongooseJsonParse.js:19:19:19:20 | {} |
| mongooseJsonParse.js:20:19:20:44 | JSON.pa ... y.data) |
@@ -156,12 +160,12 @@ nodes
| tst2.js:9:27:9:84 | "select ... d + "'" |
| tst2.js:9:66:9:78 | req.params.id |
| tst2.js:9:66:9:78 | req.params.id |
-| tst3.js:8:7:9:55 | query1 |
-| tst3.js:8:16:9:55 | "SELECT ... PRICE" |
-| tst3.js:9:16:9:34 | req.params.category |
-| tst3.js:9:16:9:34 | req.params.category |
-| tst3.js:10:14:10:19 | query1 |
-| tst3.js:10:14:10:19 | query1 |
+| tst3.js:7:7:8:55 | query1 |
+| tst3.js:7:16:8:55 | "SELECT ... PRICE" |
+| tst3.js:8:16:8:34 | req.params.category |
+| tst3.js:8:16:8:34 | req.params.category |
+| tst3.js:9:14:9:19 | query1 |
+| tst3.js:9:14:9:19 | query1 |
| tst4.js:8:10:8:66 | 'SELECT ... d + '"' |
| tst4.js:8:10:8:66 | 'SELECT ... d + '"' |
| tst4.js:8:46:8:60 | $routeParams.id |
@@ -288,30 +292,34 @@ edges
| mongoose.js:20:11:20:20 | query | mongoose.js:67:27:67:31 | query |
| mongoose.js:20:11:20:20 | query | mongoose.js:68:8:68:12 | query |
| mongoose.js:20:11:20:20 | query | mongoose.js:68:8:68:12 | query |
-| mongoose.js:20:11:20:20 | query | mongoose.js:72:8:72:12 | query |
-| mongoose.js:20:11:20:20 | query | mongoose.js:72:8:72:12 | query |
-| mongoose.js:20:11:20:20 | query | mongoose.js:73:7:73:11 | query |
-| mongoose.js:20:11:20:20 | query | mongoose.js:73:7:73:11 | query |
-| mongoose.js:20:11:20:20 | query | mongoose.js:74:16:74:20 | query |
-| mongoose.js:20:11:20:20 | query | mongoose.js:74:16:74:20 | query |
-| mongoose.js:20:11:20:20 | query | mongoose.js:76:10:76:14 | query |
-| mongoose.js:20:11:20:20 | query | mongoose.js:76:10:76:14 | query |
-| mongoose.js:20:11:20:20 | query | mongoose.js:81:46:81:50 | query |
-| mongoose.js:20:11:20:20 | query | mongoose.js:81:46:81:50 | query |
-| mongoose.js:20:11:20:20 | query | mongoose.js:82:47:82:51 | query |
-| mongoose.js:20:11:20:20 | query | mongoose.js:82:47:82:51 | query |
-| mongoose.js:20:11:20:20 | query | mongoose.js:84:46:84:50 | query |
-| mongoose.js:20:11:20:20 | query | mongoose.js:84:46:84:50 | query |
-| mongoose.js:20:11:20:20 | query | mongoose.js:86:51:86:55 | query |
-| mongoose.js:20:11:20:20 | query | mongoose.js:86:51:86:55 | query |
-| mongoose.js:20:11:20:20 | query | mongoose.js:88:46:88:50 | query |
-| mongoose.js:20:11:20:20 | query | mongoose.js:88:46:88:50 | query |
-| mongoose.js:20:11:20:20 | query | mongoose.js:91:46:91:50 | query |
-| mongoose.js:20:11:20:20 | query | mongoose.js:91:46:91:50 | query |
-| mongoose.js:20:11:20:20 | query | mongoose.js:93:51:93:55 | query |
-| mongoose.js:20:11:20:20 | query | mongoose.js:93:51:93:55 | query |
-| mongoose.js:20:11:20:20 | query | mongoose.js:95:46:95:50 | query |
-| mongoose.js:20:11:20:20 | query | mongoose.js:95:46:95:50 | query |
+| mongoose.js:20:11:20:20 | query | mongoose.js:71:20:71:24 | query |
+| mongoose.js:20:11:20:20 | query | mongoose.js:71:20:71:24 | query |
+| mongoose.js:20:11:20:20 | query | mongoose.js:72:16:72:20 | query |
+| mongoose.js:20:11:20:20 | query | mongoose.js:72:16:72:20 | query |
+| mongoose.js:20:11:20:20 | query | mongoose.js:73:8:73:12 | query |
+| mongoose.js:20:11:20:20 | query | mongoose.js:73:8:73:12 | query |
+| mongoose.js:20:11:20:20 | query | mongoose.js:74:7:74:11 | query |
+| mongoose.js:20:11:20:20 | query | mongoose.js:74:7:74:11 | query |
+| mongoose.js:20:11:20:20 | query | mongoose.js:75:16:75:20 | query |
+| mongoose.js:20:11:20:20 | query | mongoose.js:75:16:75:20 | query |
+| mongoose.js:20:11:20:20 | query | mongoose.js:77:10:77:14 | query |
+| mongoose.js:20:11:20:20 | query | mongoose.js:77:10:77:14 | query |
+| mongoose.js:20:11:20:20 | query | mongoose.js:82:46:82:50 | query |
+| mongoose.js:20:11:20:20 | query | mongoose.js:82:46:82:50 | query |
+| mongoose.js:20:11:20:20 | query | mongoose.js:83:47:83:51 | query |
+| mongoose.js:20:11:20:20 | query | mongoose.js:83:47:83:51 | query |
+| mongoose.js:20:11:20:20 | query | mongoose.js:85:46:85:50 | query |
+| mongoose.js:20:11:20:20 | query | mongoose.js:85:46:85:50 | query |
+| mongoose.js:20:11:20:20 | query | mongoose.js:87:51:87:55 | query |
+| mongoose.js:20:11:20:20 | query | mongoose.js:87:51:87:55 | query |
+| mongoose.js:20:11:20:20 | query | mongoose.js:89:46:89:50 | query |
+| mongoose.js:20:11:20:20 | query | mongoose.js:89:46:89:50 | query |
+| mongoose.js:20:11:20:20 | query | mongoose.js:92:46:92:50 | query |
+| mongoose.js:20:11:20:20 | query | mongoose.js:92:46:92:50 | query |
+| mongoose.js:20:11:20:20 | query | mongoose.js:94:51:94:55 | query |
+| mongoose.js:20:11:20:20 | query | mongoose.js:94:51:94:55 | query |
+| mongoose.js:20:11:20:20 | query | mongoose.js:96:46:96:50 | query |
+| mongoose.js:20:11:20:20 | query | mongoose.js:96:46:96:50 | query |
| mongoose.js:20:19:20:20 | {} | mongoose.js:20:11:20:20 | query |
| mongoose.js:21:19:21:26 | req.body | mongoose.js:21:19:21:32 | req.body.title |
| mongoose.js:21:19:21:26 | req.body | mongoose.js:21:19:21:32 | req.body.title |
@@ -350,30 +358,34 @@ edges
| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:67:27:67:31 | query |
| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:68:8:68:12 | query |
| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:68:8:68:12 | query |
-| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:72:8:72:12 | query |
-| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:72:8:72:12 | query |
-| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:73:7:73:11 | query |
-| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:73:7:73:11 | query |
-| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:74:16:74:20 | query |
-| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:74:16:74:20 | query |
-| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:76:10:76:14 | query |
-| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:76:10:76:14 | query |
-| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:81:46:81:50 | query |
-| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:81:46:81:50 | query |
-| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:82:47:82:51 | query |
-| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:82:47:82:51 | query |
-| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:84:46:84:50 | query |
-| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:84:46:84:50 | query |
-| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:86:51:86:55 | query |
-| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:86:51:86:55 | query |
-| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:88:46:88:50 | query |
-| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:88:46:88:50 | query |
-| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:91:46:91:50 | query |
-| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:91:46:91:50 | query |
-| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:93:51:93:55 | query |
-| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:93:51:93:55 | query |
-| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:95:46:95:50 | query |
-| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:95:46:95:50 | query |
+| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:71:20:71:24 | query |
+| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:71:20:71:24 | query |
+| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:72:16:72:20 | query |
+| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:72:16:72:20 | query |
+| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:73:8:73:12 | query |
+| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:73:8:73:12 | query |
+| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:74:7:74:11 | query |
+| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:74:7:74:11 | query |
+| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:75:16:75:20 | query |
+| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:75:16:75:20 | query |
+| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:77:10:77:14 | query |
+| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:77:10:77:14 | query |
+| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:82:46:82:50 | query |
+| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:82:46:82:50 | query |
+| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:83:47:83:51 | query |
+| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:83:47:83:51 | query |
+| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:85:46:85:50 | query |
+| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:85:46:85:50 | query |
+| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:87:51:87:55 | query |
+| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:87:51:87:55 | query |
+| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:89:46:89:50 | query |
+| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:89:46:89:50 | query |
+| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:92:46:92:50 | query |
+| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:92:46:92:50 | query |
+| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:94:51:94:55 | query |
+| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:94:51:94:55 | query |
+| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:96:46:96:50 | query |
+| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:96:46:96:50 | query |
| mongoose.js:24:25:24:29 | query | mongoose.js:24:24:24:30 | [query] |
| mongoose.js:24:25:24:29 | query | mongoose.js:24:24:24:30 | [query] |
| mongooseJsonParse.js:19:11:19:20 | query | mongooseJsonParse.js:23:19:23:23 | query |
@@ -405,11 +417,11 @@ edges
| tst2.js:9:66:9:78 | req.params.id | tst2.js:9:27:9:84 | "select ... d + "'" |
| tst2.js:9:66:9:78 | req.params.id | tst2.js:9:27:9:84 | "select ... d + "'" |
| tst2.js:9:66:9:78 | req.params.id | tst2.js:9:27:9:84 | "select ... d + "'" |
-| tst3.js:8:7:9:55 | query1 | tst3.js:10:14:10:19 | query1 |
-| tst3.js:8:7:9:55 | query1 | tst3.js:10:14:10:19 | query1 |
-| tst3.js:8:16:9:55 | "SELECT ... PRICE" | tst3.js:8:7:9:55 | query1 |
-| tst3.js:9:16:9:34 | req.params.category | tst3.js:8:16:9:55 | "SELECT ... PRICE" |
-| tst3.js:9:16:9:34 | req.params.category | tst3.js:8:16:9:55 | "SELECT ... PRICE" |
+| tst3.js:7:7:8:55 | query1 | tst3.js:9:14:9:19 | query1 |
+| tst3.js:7:7:8:55 | query1 | tst3.js:9:14:9:19 | query1 |
+| tst3.js:7:16:8:55 | "SELECT ... PRICE" | tst3.js:7:7:8:55 | query1 |
+| tst3.js:8:16:8:34 | req.params.category | tst3.js:7:16:8:55 | "SELECT ... PRICE" |
+| tst3.js:8:16:8:34 | req.params.category | tst3.js:7:16:8:55 | "SELECT ... PRICE" |
| tst4.js:8:46:8:60 | $routeParams.id | tst4.js:8:10:8:66 | 'SELECT ... d + '"' |
| tst4.js:8:46:8:60 | $routeParams.id | tst4.js:8:10:8:66 | 'SELECT ... d + '"' |
| tst4.js:8:46:8:60 | $routeParams.id | tst4.js:8:10:8:66 | 'SELECT ... d + '"' |
@@ -446,23 +458,25 @@ edges
| mongoose.js:65:32:65:36 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:65:32:65:36 | query | This query depends on $@. | mongoose.js:21:19:21:26 | req.body | a user-provided value |
| mongoose.js:67:27:67:31 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:67:27:67:31 | query | This query depends on $@. | mongoose.js:21:19:21:26 | req.body | a user-provided value |
| mongoose.js:68:8:68:12 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:68:8:68:12 | query | This query depends on $@. | mongoose.js:21:19:21:26 | req.body | a user-provided value |
-| mongoose.js:72:8:72:12 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:72:8:72:12 | query | This query depends on $@. | mongoose.js:21:19:21:26 | req.body | a user-provided value |
-| mongoose.js:73:7:73:11 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:73:7:73:11 | query | This query depends on $@. | mongoose.js:21:19:21:26 | req.body | a user-provided value |
-| mongoose.js:74:16:74:20 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:74:16:74:20 | query | This query depends on $@. | mongoose.js:21:19:21:26 | req.body | a user-provided value |
-| mongoose.js:76:10:76:14 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:76:10:76:14 | query | This query depends on $@. | mongoose.js:21:19:21:26 | req.body | a user-provided value |
-| mongoose.js:81:46:81:50 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:81:46:81:50 | query | This query depends on $@. | mongoose.js:21:19:21:26 | req.body | a user-provided value |
-| mongoose.js:82:47:82:51 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:82:47:82:51 | query | This query depends on $@. | mongoose.js:21:19:21:26 | req.body | a user-provided value |
-| mongoose.js:84:46:84:50 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:84:46:84:50 | query | This query depends on $@. | mongoose.js:21:19:21:26 | req.body | a user-provided value |
-| mongoose.js:86:51:86:55 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:86:51:86:55 | query | This query depends on $@. | mongoose.js:21:19:21:26 | req.body | a user-provided value |
-| mongoose.js:88:46:88:50 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:88:46:88:50 | query | This query depends on $@. | mongoose.js:21:19:21:26 | req.body | a user-provided value |
-| mongoose.js:91:46:91:50 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:91:46:91:50 | query | This query depends on $@. | mongoose.js:21:19:21:26 | req.body | a user-provided value |
-| mongoose.js:93:51:93:55 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:93:51:93:55 | query | This query depends on $@. | mongoose.js:21:19:21:26 | req.body | a user-provided value |
-| mongoose.js:95:46:95:50 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:95:46:95:50 | query | This query depends on $@. | mongoose.js:21:19:21:26 | req.body | a user-provided value |
+| mongoose.js:71:20:71:24 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:71:20:71:24 | query | This query depends on $@. | mongoose.js:21:19:21:26 | req.body | a user-provided value |
+| mongoose.js:72:16:72:20 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:72:16:72:20 | query | This query depends on $@. | mongoose.js:21:19:21:26 | req.body | a user-provided value |
+| mongoose.js:73:8:73:12 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:73:8:73:12 | query | This query depends on $@. | mongoose.js:21:19:21:26 | req.body | a user-provided value |
+| mongoose.js:74:7:74:11 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:74:7:74:11 | query | This query depends on $@. | mongoose.js:21:19:21:26 | req.body | a user-provided value |
+| mongoose.js:75:16:75:20 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:75:16:75:20 | query | This query depends on $@. | mongoose.js:21:19:21:26 | req.body | a user-provided value |
+| mongoose.js:77:10:77:14 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:77:10:77:14 | query | This query depends on $@. | mongoose.js:21:19:21:26 | req.body | a user-provided value |
+| mongoose.js:82:46:82:50 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:82:46:82:50 | query | This query depends on $@. | mongoose.js:21:19:21:26 | req.body | a user-provided value |
+| mongoose.js:83:47:83:51 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:83:47:83:51 | query | This query depends on $@. | mongoose.js:21:19:21:26 | req.body | a user-provided value |
+| mongoose.js:85:46:85:50 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:85:46:85:50 | query | This query depends on $@. | mongoose.js:21:19:21:26 | req.body | a user-provided value |
+| mongoose.js:87:51:87:55 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:87:51:87:55 | query | This query depends on $@. | mongoose.js:21:19:21:26 | req.body | a user-provided value |
+| mongoose.js:89:46:89:50 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:89:46:89:50 | query | This query depends on $@. | mongoose.js:21:19:21:26 | req.body | a user-provided value |
+| mongoose.js:92:46:92:50 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:92:46:92:50 | query | This query depends on $@. | mongoose.js:21:19:21:26 | req.body | a user-provided value |
+| mongoose.js:94:51:94:55 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:94:51:94:55 | query | This query depends on $@. | mongoose.js:21:19:21:26 | req.body | a user-provided value |
+| mongoose.js:96:46:96:50 | query | mongoose.js:21:19:21:26 | req.body | mongoose.js:96:46:96:50 | query | This query depends on $@. | mongoose.js:21:19:21:26 | req.body | a user-provided value |
| mongooseJsonParse.js:23:19:23:23 | query | mongooseJsonParse.js:20:30:20:43 | req.query.data | mongooseJsonParse.js:23:19:23:23 | query | This query depends on $@. | mongooseJsonParse.js:20:30:20:43 | req.query.data | a user-provided value |
| mongooseModelClient.js:11:16:11:24 | { id: v } | mongooseModelClient.js:10:22:10:29 | req.body | mongooseModelClient.js:11:16:11:24 | { id: v } | This query depends on $@. | mongooseModelClient.js:10:22:10:29 | req.body | a user-provided value |
| mongooseModelClient.js:12:16:12:34 | { id: req.body.id } | mongooseModelClient.js:12:22:12:29 | req.body | mongooseModelClient.js:12:16:12:34 | { id: req.body.id } | This query depends on $@. | mongooseModelClient.js:12:22:12:29 | req.body | a user-provided value |
| socketio.js:11:12:11:53 | `INSERT ... andle}` | socketio.js:10:25:10:30 | handle | socketio.js:11:12:11:53 | `INSERT ... andle}` | This query depends on $@. | socketio.js:10:25:10:30 | handle | a user-provided value |
| tst2.js:9:27:9:84 | "select ... d + "'" | tst2.js:9:66:9:78 | req.params.id | tst2.js:9:27:9:84 | "select ... d + "'" | This query depends on $@. | tst2.js:9:66:9:78 | req.params.id | a user-provided value |
-| tst3.js:10:14:10:19 | query1 | tst3.js:9:16:9:34 | req.params.category | tst3.js:10:14:10:19 | query1 | This query depends on $@. | tst3.js:9:16:9:34 | req.params.category | a user-provided value |
+| tst3.js:9:14:9:19 | query1 | tst3.js:8:16:8:34 | req.params.category | tst3.js:9:14:9:19 | query1 | This query depends on $@. | tst3.js:8:16:8:34 | req.params.category | a user-provided value |
| tst4.js:8:10:8:66 | 'SELECT ... d + '"' | tst4.js:8:46:8:60 | $routeParams.id | tst4.js:8:10:8:66 | 'SELECT ... d + '"' | This query depends on $@. | tst4.js:8:46:8:60 | $routeParams.id | a user-provided value |
| tst.js:10:10:10:64 | 'SELECT ... d + '"' | tst.js:10:46:10:58 | req.params.id | tst.js:10:10:10:64 | 'SELECT ... d + '"' | This query depends on $@. | tst.js:10:46:10:58 | req.params.id | a user-provided value |
diff --git a/javascript/ql/test/query-tests/Security/CWE-089/untyped/mongoose.js b/javascript/ql/test/query-tests/Security/CWE-089/untyped/mongoose.js
index a6875539896f..03e149b7c02a 100644
--- a/javascript/ql/test/query-tests/Security/CWE-089/untyped/mongoose.js
+++ b/javascript/ql/test/query-tests/Security/CWE-089/untyped/mongoose.js
@@ -68,7 +68,8 @@ app.post('/documents/find', (req, res) => {
.and(query, function(){}) // NOT OK
;
- Document.where(query) // NOT OK
+ Document.where(query) // NOT OK - `.where()` on a Model.
+ .where(query) // NOT OK - `.where()` on a Query.
.and(query) // NOT OK
.or(query) // NOT OK
.distinct(X, query) // NOT OK
diff --git a/javascript/ql/test/query-tests/Security/CWE-089/untyped/tst3.js b/javascript/ql/test/query-tests/Security/CWE-089/untyped/tst3.js
index e47c1a4ec9d4..3f9aa21355d1 100644
--- a/javascript/ql/test/query-tests/Security/CWE-089/untyped/tst3.js
+++ b/javascript/ql/test/query-tests/Security/CWE-089/untyped/tst3.js
@@ -4,10 +4,9 @@ const pg = require('pg');
const pool = new pg.Pool(config);
function handler(req, res) {
- // BAD: the category might have SQL special characters in it
var query1 = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='"
+ req.params.category + "' ORDER BY PRICE";
- pool.query(query1, [], function(err, results) {
+ pool.query(query1, [], function(err, results) { // BAD: the category might have SQL special characters in it
// process results
});
diff --git a/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/NoSQLCodeInjection.js b/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/NoSQLCodeInjection.js
index d077fce60731..3e7025a8e6cd 100644
--- a/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/NoSQLCodeInjection.js
+++ b/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/NoSQLCodeInjection.js
@@ -14,7 +14,7 @@ app.post("/documents/find", (req, res) => {
MongoClient.connect("mongodb://localhost:27017/test", (err, db) => {
let doc = db.collection("doc");
- doc.find(query); // NOT OK, but that is flagged by js/sql-injection
+ doc.find(query); // NOT OK, but that is flagged by js/sql-injection [INCONSISTENCY]
doc.find({ $where: req.body.query }); // NOT OK
doc.find({ $where: "name = " + req.body.name }); // NOT OK
});
diff --git a/javascript/ql/test/query-tests/Security/CWE-312/passwords.js b/javascript/ql/test/query-tests/Security/CWE-312/passwords.js
index 448a972ee8fa..50dc80a65d0b 100644
--- a/javascript/ql/test/query-tests/Security/CWE-312/passwords.js
+++ b/javascript/ql/test/query-tests/Security/CWE-312/passwords.js
@@ -26,8 +26,8 @@
console.log(obj2); // NOT OK
var obj3 = {};
- console.log(obj3);
- obj3.x = password; // NOT OK
+ console.log(obj3); // OK - but still flagged due to flow-insensitive field-analysis. [INCONSISTENCY]
+ obj3.x = password;
var fixed_password = "123";
console.log(fixed_password); // OK
@@ -90,12 +90,12 @@
console.log("Password is: " + redact('password', password));
if (environment.isTestEnv()) {
- console.log("Password is: " + password); // OK, but still flagged
+ console.log("Password is: " + password); // OK, but still flagged [INCONSISTENCY]
}
if (environment.is(TEST)) {
// NB: for security reasons, we only log passwords in test environments
- console.log("Password is: " + password); // OK, but still flagged
+ console.log("Password is: " + password); // OK, but still flagged [INCONSISTENCY]
}
@@ -107,7 +107,7 @@
}
if (environment.isTestEnv())
- console.log("Password is: " + password); // OK, but still flagged
+ console.log("Password is: " + password); // OK, but still flagged [INCONSISTENCY]
if (x.test(y)) {
if (f()) {
@@ -116,7 +116,7 @@
}
if (!environment.isProduction()) {
- console.log("Password is: " + password); // OK, but still flagged
+ console.log("Password is: " + password); // OK, but still flagged [INCONSISTENCY]
}
console.log(name + ", " + password.toString()); // NOT OK
diff --git a/javascript/ql/test/query-tests/Security/CWE-338/tst.js b/javascript/ql/test/query-tests/Security/CWE-338/tst.js
index 56fec7c94e6f..123799426b55 100644
--- a/javascript/ql/test/query-tests/Security/CWE-338/tst.js
+++ b/javascript/ql/test/query-tests/Security/CWE-338/tst.js
@@ -21,7 +21,7 @@ function f4() {
}
function f5() {
- var pw = Math.random(); // NOT OK, but our naming heuristic does not identify `pw` as sensitive
+ var pw = Math.random(); // NOT OK, but our naming heuristic does not identify `pw` as sensitive [INCONSISTENCY]
}
function f6() {
diff --git a/javascript/ql/test/query-tests/Security/CWE-346/tst.js b/javascript/ql/test/query-tests/Security/CWE-346/tst.js
index 0d39b3cbe41e..3b22ace123d6 100644
--- a/javascript/ql/test/query-tests/Security/CWE-346/tst.js
+++ b/javascript/ql/test/query-tests/Security/CWE-346/tst.js
@@ -48,7 +48,7 @@ server.on('request', (req, res) => {
// syntactic header defintion
probalyAServer.on('request', (req, res) => {
- res.setHeader("Access-Control-Allow-Origin", null); // NOT OK (but not detected)
+ res.setHeader("Access-Control-Allow-Origin", null); // NOT OK (but not detected) [INCONSISTENCY]
res.setHeader("Access-Control-Allow-Credentials", true);
});
diff --git a/javascript/ql/test/query-tests/Security/CWE-506/tst.js b/javascript/ql/test/query-tests/Security/CWE-506/tst.js
index 64e3ca0101c4..e2e557ead7da 100644
--- a/javascript/ql/test/query-tests/Security/CWE-506/tst.js
+++ b/javascript/ql/test/query-tests/Security/CWE-506/tst.js
@@ -4,7 +4,7 @@ eval(totallyHarmlessString); // OK: throws parse
var test = "0123456789";
try {
- eval(test+"n"); // OK, but currently flagged
+ eval(test+"n"); // OK, but currently flagged [INCONSISTENCY]
console.log("Bigints supported.");
} catch(e) {
console.log("Bigints not supported.");
diff --git a/javascript/ql/test/query-tests/Security/CWE-601/ServerSideUrlRedirect/ServerSideUrlRedirect.expected b/javascript/ql/test/query-tests/Security/CWE-601/ServerSideUrlRedirect/ServerSideUrlRedirect.expected
index 3693690ca525..299c434f3295 100644
--- a/javascript/ql/test/query-tests/Security/CWE-601/ServerSideUrlRedirect/ServerSideUrlRedirect.expected
+++ b/javascript/ql/test/query-tests/Security/CWE-601/ServerSideUrlRedirect/ServerSideUrlRedirect.expected
@@ -56,32 +56,32 @@ nodes
| koa.js:14:16:14:18 | url |
| koa.js:20:16:20:18 | url |
| koa.js:20:16:20:18 | url |
-| node.js:6:7:6:52 | target |
-| node.js:6:16:6:39 | url.par ... , true) |
-| node.js:6:16:6:45 | url.par ... ).query |
-| node.js:6:16:6:52 | url.par ... .target |
-| node.js:6:26:6:32 | req.url |
-| node.js:6:26:6:32 | req.url |
-| node.js:7:34:7:39 | target |
-| node.js:7:34:7:39 | target |
-| node.js:11:7:11:52 | target |
-| node.js:11:16:11:39 | url.par ... , true) |
-| node.js:11:16:11:45 | url.par ... ).query |
-| node.js:11:16:11:52 | url.par ... .target |
-| node.js:11:26:11:32 | req.url |
-| node.js:11:26:11:32 | req.url |
-| node.js:15:34:15:45 | '/' + target |
-| node.js:15:34:15:45 | '/' + target |
-| node.js:15:40:15:45 | target |
-| node.js:29:7:29:52 | target |
-| node.js:29:16:29:39 | url.par ... , true) |
-| node.js:29:16:29:45 | url.par ... ).query |
-| node.js:29:16:29:52 | url.par ... .target |
-| node.js:29:26:29:32 | req.url |
-| node.js:29:26:29:32 | req.url |
-| node.js:32:34:32:39 | target |
-| node.js:32:34:32:55 | target ... =" + me |
-| node.js:32:34:32:55 | target ... =" + me |
+| node.js:5:7:5:52 | target |
+| node.js:5:16:5:39 | url.par ... , true) |
+| node.js:5:16:5:45 | url.par ... ).query |
+| node.js:5:16:5:52 | url.par ... .target |
+| node.js:5:26:5:32 | req.url |
+| node.js:5:26:5:32 | req.url |
+| node.js:6:34:6:39 | target |
+| node.js:6:34:6:39 | target |
+| node.js:10:7:10:52 | target |
+| node.js:10:16:10:39 | url.par ... , true) |
+| node.js:10:16:10:45 | url.par ... ).query |
+| node.js:10:16:10:52 | url.par ... .target |
+| node.js:10:26:10:32 | req.url |
+| node.js:10:26:10:32 | req.url |
+| node.js:14:34:14:45 | '/' + target |
+| node.js:14:34:14:45 | '/' + target |
+| node.js:14:40:14:45 | target |
+| node.js:28:7:28:52 | target |
+| node.js:28:16:28:39 | url.par ... , true) |
+| node.js:28:16:28:45 | url.par ... ).query |
+| node.js:28:16:28:52 | url.par ... .target |
+| node.js:28:26:28:32 | req.url |
+| node.js:28:26:28:32 | req.url |
+| node.js:31:34:31:39 | target |
+| node.js:31:34:31:55 | target ... =" + me |
+| node.js:31:34:31:55 | target ... =" + me |
| react-native.js:7:7:7:33 | tainted |
| react-native.js:7:17:7:33 | req.param("code") |
| react-native.js:7:17:7:33 | req.param("code") |
@@ -139,29 +139,29 @@ edges
| koa.js:6:12:6:27 | ctx.query.target | koa.js:6:6:6:27 | url |
| koa.js:8:18:8:20 | url | koa.js:8:15:8:26 | `${url}${x}` |
| koa.js:8:18:8:20 | url | koa.js:8:15:8:26 | `${url}${x}` |
-| node.js:6:7:6:52 | target | node.js:7:34:7:39 | target |
-| node.js:6:7:6:52 | target | node.js:7:34:7:39 | target |
-| node.js:6:16:6:39 | url.par ... , true) | node.js:6:16:6:45 | url.par ... ).query |
-| node.js:6:16:6:45 | url.par ... ).query | node.js:6:16:6:52 | url.par ... .target |
-| node.js:6:16:6:52 | url.par ... .target | node.js:6:7:6:52 | target |
-| node.js:6:26:6:32 | req.url | node.js:6:16:6:39 | url.par ... , true) |
-| node.js:6:26:6:32 | req.url | node.js:6:16:6:39 | url.par ... , true) |
-| node.js:11:7:11:52 | target | node.js:15:40:15:45 | target |
-| node.js:11:16:11:39 | url.par ... , true) | node.js:11:16:11:45 | url.par ... ).query |
-| node.js:11:16:11:45 | url.par ... ).query | node.js:11:16:11:52 | url.par ... .target |
-| node.js:11:16:11:52 | url.par ... .target | node.js:11:7:11:52 | target |
-| node.js:11:26:11:32 | req.url | node.js:11:16:11:39 | url.par ... , true) |
-| node.js:11:26:11:32 | req.url | node.js:11:16:11:39 | url.par ... , true) |
-| node.js:15:40:15:45 | target | node.js:15:34:15:45 | '/' + target |
-| node.js:15:40:15:45 | target | node.js:15:34:15:45 | '/' + target |
-| node.js:29:7:29:52 | target | node.js:32:34:32:39 | target |
-| node.js:29:16:29:39 | url.par ... , true) | node.js:29:16:29:45 | url.par ... ).query |
-| node.js:29:16:29:45 | url.par ... ).query | node.js:29:16:29:52 | url.par ... .target |
-| node.js:29:16:29:52 | url.par ... .target | node.js:29:7:29:52 | target |
-| node.js:29:26:29:32 | req.url | node.js:29:16:29:39 | url.par ... , true) |
-| node.js:29:26:29:32 | req.url | node.js:29:16:29:39 | url.par ... , true) |
-| node.js:32:34:32:39 | target | node.js:32:34:32:55 | target ... =" + me |
-| node.js:32:34:32:39 | target | node.js:32:34:32:55 | target ... =" + me |
+| node.js:5:7:5:52 | target | node.js:6:34:6:39 | target |
+| node.js:5:7:5:52 | target | node.js:6:34:6:39 | target |
+| node.js:5:16:5:39 | url.par ... , true) | node.js:5:16:5:45 | url.par ... ).query |
+| node.js:5:16:5:45 | url.par ... ).query | node.js:5:16:5:52 | url.par ... .target |
+| node.js:5:16:5:52 | url.par ... .target | node.js:5:7:5:52 | target |
+| node.js:5:26:5:32 | req.url | node.js:5:16:5:39 | url.par ... , true) |
+| node.js:5:26:5:32 | req.url | node.js:5:16:5:39 | url.par ... , true) |
+| node.js:10:7:10:52 | target | node.js:14:40:14:45 | target |
+| node.js:10:16:10:39 | url.par ... , true) | node.js:10:16:10:45 | url.par ... ).query |
+| node.js:10:16:10:45 | url.par ... ).query | node.js:10:16:10:52 | url.par ... .target |
+| node.js:10:16:10:52 | url.par ... .target | node.js:10:7:10:52 | target |
+| node.js:10:26:10:32 | req.url | node.js:10:16:10:39 | url.par ... , true) |
+| node.js:10:26:10:32 | req.url | node.js:10:16:10:39 | url.par ... , true) |
+| node.js:14:40:14:45 | target | node.js:14:34:14:45 | '/' + target |
+| node.js:14:40:14:45 | target | node.js:14:34:14:45 | '/' + target |
+| node.js:28:7:28:52 | target | node.js:31:34:31:39 | target |
+| node.js:28:16:28:39 | url.par ... , true) | node.js:28:16:28:45 | url.par ... ).query |
+| node.js:28:16:28:45 | url.par ... ).query | node.js:28:16:28:52 | url.par ... .target |
+| node.js:28:16:28:52 | url.par ... .target | node.js:28:7:28:52 | target |
+| node.js:28:26:28:32 | req.url | node.js:28:16:28:39 | url.par ... , true) |
+| node.js:28:26:28:32 | req.url | node.js:28:16:28:39 | url.par ... , true) |
+| node.js:31:34:31:39 | target | node.js:31:34:31:55 | target ... =" + me |
+| node.js:31:34:31:39 | target | node.js:31:34:31:55 | target ... =" + me |
| react-native.js:7:7:7:33 | tainted | react-native.js:8:17:8:23 | tainted |
| react-native.js:7:7:7:33 | tainted | react-native.js:8:17:8:23 | tainted |
| react-native.js:7:7:7:33 | tainted | react-native.js:9:26:9:32 | tainted |
@@ -185,8 +185,8 @@ edges
| koa.js:8:15:8:26 | `${url}${x}` | koa.js:6:12:6:27 | ctx.query.target | koa.js:8:15:8:26 | `${url}${x}` | Untrusted URL redirection due to $@. | koa.js:6:12:6:27 | ctx.query.target | user-provided value |
| koa.js:14:16:14:18 | url | koa.js:6:12:6:27 | ctx.query.target | koa.js:14:16:14:18 | url | Untrusted URL redirection due to $@. | koa.js:6:12:6:27 | ctx.query.target | user-provided value |
| koa.js:20:16:20:18 | url | koa.js:6:12:6:27 | ctx.query.target | koa.js:20:16:20:18 | url | Untrusted URL redirection due to $@. | koa.js:6:12:6:27 | ctx.query.target | user-provided value |
-| node.js:7:34:7:39 | target | node.js:6:26:6:32 | req.url | node.js:7:34:7:39 | target | Untrusted URL redirection due to $@. | node.js:6:26:6:32 | req.url | user-provided value |
-| node.js:15:34:15:45 | '/' + target | node.js:11:26:11:32 | req.url | node.js:15:34:15:45 | '/' + target | Untrusted URL redirection due to $@. | node.js:11:26:11:32 | req.url | user-provided value |
-| node.js:32:34:32:55 | target ... =" + me | node.js:29:26:29:32 | req.url | node.js:32:34:32:55 | target ... =" + me | Untrusted URL redirection due to $@. | node.js:29:26:29:32 | req.url | user-provided value |
+| node.js:6:34:6:39 | target | node.js:5:26:5:32 | req.url | node.js:6:34:6:39 | target | Untrusted URL redirection due to $@. | node.js:5:26:5:32 | req.url | user-provided value |
+| node.js:14:34:14:45 | '/' + target | node.js:10:26:10:32 | req.url | node.js:14:34:14:45 | '/' + target | Untrusted URL redirection due to $@. | node.js:10:26:10:32 | req.url | user-provided value |
+| node.js:31:34:31:55 | target ... =" + me | node.js:28:26:28:32 | req.url | node.js:31:34:31:55 | target ... =" + me | Untrusted URL redirection due to $@. | node.js:28:26:28:32 | req.url | user-provided value |
| react-native.js:8:17:8:23 | tainted | react-native.js:7:17:7:33 | req.param("code") | react-native.js:8:17:8:23 | tainted | Untrusted URL redirection due to $@. | react-native.js:7:17:7:33 | req.param("code") | user-provided value |
| react-native.js:9:26:9:32 | tainted | react-native.js:7:17:7:33 | req.param("code") | react-native.js:9:26:9:32 | tainted | Untrusted URL redirection due to $@. | react-native.js:7:17:7:33 | req.param("code") | user-provided value |
diff --git a/javascript/ql/test/query-tests/Security/CWE-601/ServerSideUrlRedirect/express.js b/javascript/ql/test/query-tests/Security/CWE-601/ServerSideUrlRedirect/express.js
index 869f3f5686bf..4c7c476a0605 100644
--- a/javascript/ql/test/query-tests/Security/CWE-601/ServerSideUrlRedirect/express.js
+++ b/javascript/ql/test/query-tests/Security/CWE-601/ServerSideUrlRedirect/express.js
@@ -135,6 +135,6 @@ app.get('/redirect/:user', function(req, res) {
res.redirect('//' + req.params.user); // BAD - could go to //evil.com
res.redirect('u' + req.params.user); // BAD - could go to u.evil.com
- res.redirect('/' + ('/u' + req.params.user)); // BAD - could go to //u.evil.com, but not flagged
+ res.redirect('/' + ('/u' + req.params.user)); // BAD - could go to //u.evil.com, but not flagged [INCONSISTENCY]
res.redirect('/u' + req.params.user); // GOOD
});
diff --git a/javascript/ql/test/query-tests/Security/CWE-601/ServerSideUrlRedirect/node.js b/javascript/ql/test/query-tests/Security/CWE-601/ServerSideUrlRedirect/node.js
index 1c648f8d2662..499266845a28 100644
--- a/javascript/ql/test/query-tests/Security/CWE-601/ServerSideUrlRedirect/node.js
+++ b/javascript/ql/test/query-tests/Security/CWE-601/ServerSideUrlRedirect/node.js
@@ -2,9 +2,8 @@ var https = require('https');
var url = require('url');
var server = https.createServer(function(req, res) {
- // BAD: a request parameter is incorporated without validation into a URL redirect
let target = url.parse(req.url, true).query.target;
- res.writeHead(302, { Location: target });
+ res.writeHead(302, { Location: target }); // BAD: a request parameter is incorporated without validation into a URL redirect
})
server.on('request', (req, res) => {
diff --git a/javascript/ql/test/query-tests/Security/CWE-611/Xxe.expected b/javascript/ql/test/query-tests/Security/CWE-611/Xxe.expected
index 03dc33e71130..fd44e6cc756b 100644
--- a/javascript/ql/test/query-tests/Security/CWE-611/Xxe.expected
+++ b/javascript/ql/test/query-tests/Security/CWE-611/Xxe.expected
@@ -10,12 +10,12 @@ nodes
| libxml.noent.js:6:21:6:41 | req.par ... e-xml") |
| libxml.noent.js:6:21:6:41 | req.par ... e-xml") |
| libxml.noent.js:6:21:6:41 | req.par ... e-xml") |
-| libxml.sax.js:7:22:7:42 | req.par ... e-xml") |
-| libxml.sax.js:7:22:7:42 | req.par ... e-xml") |
-| libxml.sax.js:7:22:7:42 | req.par ... e-xml") |
-| libxml.saxpush.js:7:15:7:35 | req.par ... e-xml") |
-| libxml.saxpush.js:7:15:7:35 | req.par ... e-xml") |
-| libxml.saxpush.js:7:15:7:35 | req.par ... e-xml") |
+| libxml.sax.js:6:22:6:42 | req.par ... e-xml") |
+| libxml.sax.js:6:22:6:42 | req.par ... e-xml") |
+| libxml.sax.js:6:22:6:42 | req.par ... e-xml") |
+| libxml.saxpush.js:6:15:6:35 | req.par ... e-xml") |
+| libxml.saxpush.js:6:15:6:35 | req.par ... e-xml") |
+| libxml.saxpush.js:6:15:6:35 | req.par ... e-xml") |
edges
| domparser.js:2:7:2:36 | src | domparser.js:11:55:11:57 | src |
| domparser.js:2:7:2:36 | src | domparser.js:11:55:11:57 | src |
@@ -25,11 +25,11 @@ edges
| domparser.js:2:13:2:29 | document.location | domparser.js:2:13:2:36 | documen ... .search |
| domparser.js:2:13:2:36 | documen ... .search | domparser.js:2:7:2:36 | src |
| libxml.noent.js:6:21:6:41 | req.par ... e-xml") | libxml.noent.js:6:21:6:41 | req.par ... e-xml") |
-| libxml.sax.js:7:22:7:42 | req.par ... e-xml") | libxml.sax.js:7:22:7:42 | req.par ... e-xml") |
-| libxml.saxpush.js:7:15:7:35 | req.par ... e-xml") | libxml.saxpush.js:7:15:7:35 | req.par ... e-xml") |
+| libxml.sax.js:6:22:6:42 | req.par ... e-xml") | libxml.sax.js:6:22:6:42 | req.par ... e-xml") |
+| libxml.saxpush.js:6:15:6:35 | req.par ... e-xml") | libxml.saxpush.js:6:15:6:35 | req.par ... e-xml") |
#select
| domparser.js:11:55:11:57 | src | domparser.js:2:13:2:29 | document.location | domparser.js:11:55:11:57 | src | A $@ is parsed as XML without guarding against external entity expansion. | domparser.js:2:13:2:29 | document.location | user-provided value |
| domparser.js:14:57:14:59 | src | domparser.js:2:13:2:29 | document.location | domparser.js:14:57:14:59 | src | A $@ is parsed as XML without guarding against external entity expansion. | domparser.js:2:13:2:29 | document.location | user-provided value |
| libxml.noent.js:6:21:6:41 | req.par ... e-xml") | libxml.noent.js:6:21:6:41 | req.par ... e-xml") | libxml.noent.js:6:21:6:41 | req.par ... e-xml") | A $@ is parsed as XML without guarding against external entity expansion. | libxml.noent.js:6:21:6:41 | req.par ... e-xml") | user-provided value |
-| libxml.sax.js:7:22:7:42 | req.par ... e-xml") | libxml.sax.js:7:22:7:42 | req.par ... e-xml") | libxml.sax.js:7:22:7:42 | req.par ... e-xml") | A $@ is parsed as XML without guarding against external entity expansion. | libxml.sax.js:7:22:7:42 | req.par ... e-xml") | user-provided value |
-| libxml.saxpush.js:7:15:7:35 | req.par ... e-xml") | libxml.saxpush.js:7:15:7:35 | req.par ... e-xml") | libxml.saxpush.js:7:15:7:35 | req.par ... e-xml") | A $@ is parsed as XML without guarding against external entity expansion. | libxml.saxpush.js:7:15:7:35 | req.par ... e-xml") | user-provided value |
+| libxml.sax.js:6:22:6:42 | req.par ... e-xml") | libxml.sax.js:6:22:6:42 | req.par ... e-xml") | libxml.sax.js:6:22:6:42 | req.par ... e-xml") | A $@ is parsed as XML without guarding against external entity expansion. | libxml.sax.js:6:22:6:42 | req.par ... e-xml") | user-provided value |
+| libxml.saxpush.js:6:15:6:35 | req.par ... e-xml") | libxml.saxpush.js:6:15:6:35 | req.par ... e-xml") | libxml.saxpush.js:6:15:6:35 | req.par ... e-xml") | A $@ is parsed as XML without guarding against external entity expansion. | libxml.saxpush.js:6:15:6:35 | req.par ... e-xml") | user-provided value |
diff --git a/javascript/ql/test/query-tests/Security/CWE-611/libxml.sax.js b/javascript/ql/test/query-tests/Security/CWE-611/libxml.sax.js
index 3ea44a1f236b..2c837c750d32 100644
--- a/javascript/ql/test/query-tests/Security/CWE-611/libxml.sax.js
+++ b/javascript/ql/test/query-tests/Security/CWE-611/libxml.sax.js
@@ -2,7 +2,6 @@ const express = require('express');
const libxmljs = require('libxmljs');
express().get('/some/path', function(req) {
- // NOT OK: the SAX parser expands external entities by default
const parser = new libxmljs.SaxParser();
- parser.parseString(req.param("some-xml"));
+ parser.parseString(req.param("some-xml")); // NOT OK: the SAX parser expands external entities by default
});
diff --git a/javascript/ql/test/query-tests/Security/CWE-611/libxml.saxpush.js b/javascript/ql/test/query-tests/Security/CWE-611/libxml.saxpush.js
index 127c92feddbf..0e939e191c62 100644
--- a/javascript/ql/test/query-tests/Security/CWE-611/libxml.saxpush.js
+++ b/javascript/ql/test/query-tests/Security/CWE-611/libxml.saxpush.js
@@ -2,7 +2,6 @@ const express = require('express');
const libxmljs = require('libxmljs');
express().get('/some/path', function(req) {
- // NOT OK: the SAX parser expands external entities by default
const parser = new libxmljs.SaxPushParser();
- parser.push(req.param("some-xml"));
+ parser.push(req.param("some-xml")); // NOT OK: the SAX parser expands external entities by default
});
diff --git a/javascript/ql/test/query-tests/Security/CWE-730/RegExpInjection.js b/javascript/ql/test/query-tests/Security/CWE-730/RegExpInjection.js
index 2db6339c7bac..9eeadfdbe6e1 100644
--- a/javascript/ql/test/query-tests/Security/CWE-730/RegExpInjection.js
+++ b/javascript/ql/test/query-tests/Security/CWE-730/RegExpInjection.js
@@ -47,7 +47,7 @@ app.get('/findKey', function(req, res) {
maybeString.search(input); // NOT OK
notString.search(input); // OK
- URI(`${protocol}://${host}${path}`).search(input); // OK, but still flagged
+ URI(`${protocol}://${host}${path}`).search(input); // OK, but still flagged [INCONSISTENCY]
URI(`${protocol}://${host}${path}`).search(input).href(); // OK
unknown.search(input).unknown; // OK
diff --git a/javascript/ql/test/query-tests/Security/CWE-754/UnsafeDynamicMethodAccess.js b/javascript/ql/test/query-tests/Security/CWE-754/UnsafeDynamicMethodAccess.js
index 30a4d80b3131..a5124d6fd659 100644
--- a/javascript/ql/test/query-tests/Security/CWE-754/UnsafeDynamicMethodAccess.js
+++ b/javascript/ql/test/query-tests/Security/CWE-754/UnsafeDynamicMethodAccess.js
@@ -4,15 +4,15 @@ let obj = {};
window.addEventListener('message', (ev) => {
let message = JSON.parse(ev.data);
- window[message.name](message.payload); // NOT OK, but reported by UnsafeDynamicMethodAccess.ql
- new window[message.name](message.payload); // NOT OK, but reported by UnsafeDynamicMethodAccess.ql
+ window[message.name](message.payload); // NOT OK, but reported by UnsafeDynamicMethodAccess.ql [INCONSISTENCY]
+ new window[message.name](message.payload); // NOT OK, but reported by UnsafeDynamicMethodAccess.ql [INCONSISTENCY]
window["HTMLElement" + message.name](message.payload); // OK - concatenation restricts choice of methods
window[`HTMLElement${message.name}`](message.payload); // OK - concatenation restricts choice of methods
function f() {}
- f[message.name](message.payload)(); // NOT OK, but reported by UnsafeDynamicMethodAccess.ql
+ f[message.name](message.payload)(); // NOT OK, but reported by UnsafeDynamicMethodAccess.ql [INCONSISTENCY]
obj[message.name](message.payload); // NOT OK
- window[ev](ev); // NOT OK, but reported by UnsafeDynamicMethodAccess.ql
+ window[ev](ev); // NOT OK, but reported by UnsafeDynamicMethodAccess.ql [INCONSISTENCY]
});
diff --git a/javascript/ql/test/query-tests/Security/CWE-754/tst.js b/javascript/ql/test/query-tests/Security/CWE-754/tst.js
index 31622a06e488..b3c7625179a6 100644
--- a/javascript/ql/test/query-tests/Security/CWE-754/tst.js
+++ b/javascript/ql/test/query-tests/Security/CWE-754/tst.js
@@ -28,13 +28,13 @@
obj[name](); // NOT OK
if (obj.hasOwnProperty(name)) {
- obj[name](); // NOT OK, but not flagged
+ obj[name](); // NOT OK, but not flagged [INCONSISTENCY]
}
let key = "$" + name;
obj[key](); // NOT OK
if (typeof obj[key] === 'function')
- obj[key](); // OK - but still flagged
+ obj[key](); // OK - but still flagged [INCONSISTENCY]
if (typeof fn === 'function') {
fn.apply(obj); // OK
diff --git a/javascript/ql/test/query-tests/Security/CWE-776/XmlBomb.expected b/javascript/ql/test/query-tests/Security/CWE-776/XmlBomb.expected
index 77b9f6f86cac..1ba5978b9850 100644
--- a/javascript/ql/test/query-tests/Security/CWE-776/XmlBomb.expected
+++ b/javascript/ql/test/query-tests/Security/CWE-776/XmlBomb.expected
@@ -15,9 +15,9 @@ nodes
| domparser.js:11:55:11:57 | src |
| domparser.js:14:57:14:59 | src |
| domparser.js:14:57:14:59 | src |
-| expat.js:7:16:7:36 | req.par ... e-xml") |
-| expat.js:7:16:7:36 | req.par ... e-xml") |
-| expat.js:7:16:7:36 | req.par ... e-xml") |
+| expat.js:6:16:6:36 | req.par ... e-xml") |
+| expat.js:6:16:6:36 | req.par ... e-xml") |
+| expat.js:6:16:6:36 | req.par ... e-xml") |
| jquery.js:2:7:2:36 | src |
| jquery.js:2:13:2:29 | document.location |
| jquery.js:2:13:2:29 | document.location |
@@ -30,12 +30,12 @@ nodes
| libxml.noent.js:6:21:6:41 | req.par ... e-xml") |
| libxml.noent.js:6:21:6:41 | req.par ... e-xml") |
| libxml.noent.js:6:21:6:41 | req.par ... e-xml") |
-| libxml.sax.js:7:22:7:42 | req.par ... e-xml") |
-| libxml.sax.js:7:22:7:42 | req.par ... e-xml") |
-| libxml.sax.js:7:22:7:42 | req.par ... e-xml") |
-| libxml.saxpush.js:7:15:7:35 | req.par ... e-xml") |
-| libxml.saxpush.js:7:15:7:35 | req.par ... e-xml") |
-| libxml.saxpush.js:7:15:7:35 | req.par ... e-xml") |
+| libxml.sax.js:6:22:6:42 | req.par ... e-xml") |
+| libxml.sax.js:6:22:6:42 | req.par ... e-xml") |
+| libxml.sax.js:6:22:6:42 | req.par ... e-xml") |
+| libxml.saxpush.js:6:15:6:35 | req.par ... e-xml") |
+| libxml.saxpush.js:6:15:6:35 | req.par ... e-xml") |
+| libxml.saxpush.js:6:15:6:35 | req.par ... e-xml") |
edges
| closure.js:2:7:2:36 | src | closure.js:4:24:4:26 | src |
| closure.js:2:7:2:36 | src | closure.js:4:24:4:26 | src |
@@ -51,7 +51,7 @@ edges
| domparser.js:2:13:2:29 | document.location | domparser.js:2:13:2:36 | documen ... .search |
| domparser.js:2:13:2:29 | document.location | domparser.js:2:13:2:36 | documen ... .search |
| domparser.js:2:13:2:36 | documen ... .search | domparser.js:2:7:2:36 | src |
-| expat.js:7:16:7:36 | req.par ... e-xml") | expat.js:7:16:7:36 | req.par ... e-xml") |
+| expat.js:6:16:6:36 | req.par ... e-xml") | expat.js:6:16:6:36 | req.par ... e-xml") |
| jquery.js:2:7:2:36 | src | jquery.js:5:14:5:16 | src |
| jquery.js:2:7:2:36 | src | jquery.js:5:14:5:16 | src |
| jquery.js:2:13:2:29 | document.location | jquery.js:2:13:2:36 | documen ... .search |
@@ -59,16 +59,16 @@ edges
| jquery.js:2:13:2:36 | documen ... .search | jquery.js:2:7:2:36 | src |
| libxml.js:6:21:6:41 | req.par ... e-xml") | libxml.js:6:21:6:41 | req.par ... e-xml") |
| libxml.noent.js:6:21:6:41 | req.par ... e-xml") | libxml.noent.js:6:21:6:41 | req.par ... e-xml") |
-| libxml.sax.js:7:22:7:42 | req.par ... e-xml") | libxml.sax.js:7:22:7:42 | req.par ... e-xml") |
-| libxml.saxpush.js:7:15:7:35 | req.par ... e-xml") | libxml.saxpush.js:7:15:7:35 | req.par ... e-xml") |
+| libxml.sax.js:6:22:6:42 | req.par ... e-xml") | libxml.sax.js:6:22:6:42 | req.par ... e-xml") |
+| libxml.saxpush.js:6:15:6:35 | req.par ... e-xml") | libxml.saxpush.js:6:15:6:35 | req.par ... e-xml") |
#select
| closure.js:4:24:4:26 | src | closure.js:2:13:2:29 | document.location | closure.js:4:24:4:26 | src | A $@ is parsed as XML without guarding against uncontrolled entity expansion. | closure.js:2:13:2:29 | document.location | user-provided value |
| domparser.js:6:37:6:39 | src | domparser.js:2:13:2:29 | document.location | domparser.js:6:37:6:39 | src | A $@ is parsed as XML without guarding against uncontrolled entity expansion. | domparser.js:2:13:2:29 | document.location | user-provided value |
| domparser.js:11:55:11:57 | src | domparser.js:2:13:2:29 | document.location | domparser.js:11:55:11:57 | src | A $@ is parsed as XML without guarding against uncontrolled entity expansion. | domparser.js:2:13:2:29 | document.location | user-provided value |
| domparser.js:14:57:14:59 | src | domparser.js:2:13:2:29 | document.location | domparser.js:14:57:14:59 | src | A $@ is parsed as XML without guarding against uncontrolled entity expansion. | domparser.js:2:13:2:29 | document.location | user-provided value |
-| expat.js:7:16:7:36 | req.par ... e-xml") | expat.js:7:16:7:36 | req.par ... e-xml") | expat.js:7:16:7:36 | req.par ... e-xml") | A $@ is parsed as XML without guarding against uncontrolled entity expansion. | expat.js:7:16:7:36 | req.par ... e-xml") | user-provided value |
+| expat.js:6:16:6:36 | req.par ... e-xml") | expat.js:6:16:6:36 | req.par ... e-xml") | expat.js:6:16:6:36 | req.par ... e-xml") | A $@ is parsed as XML without guarding against uncontrolled entity expansion. | expat.js:6:16:6:36 | req.par ... e-xml") | user-provided value |
| jquery.js:5:14:5:16 | src | jquery.js:2:13:2:29 | document.location | jquery.js:5:14:5:16 | src | A $@ is parsed as XML without guarding against uncontrolled entity expansion. | jquery.js:2:13:2:29 | document.location | user-provided value |
| libxml.js:6:21:6:41 | req.par ... e-xml") | libxml.js:6:21:6:41 | req.par ... e-xml") | libxml.js:6:21:6:41 | req.par ... e-xml") | A $@ is parsed as XML without guarding against uncontrolled entity expansion. | libxml.js:6:21:6:41 | req.par ... e-xml") | user-provided value |
| libxml.noent.js:6:21:6:41 | req.par ... e-xml") | libxml.noent.js:6:21:6:41 | req.par ... e-xml") | libxml.noent.js:6:21:6:41 | req.par ... e-xml") | A $@ is parsed as XML without guarding against uncontrolled entity expansion. | libxml.noent.js:6:21:6:41 | req.par ... e-xml") | user-provided value |
-| libxml.sax.js:7:22:7:42 | req.par ... e-xml") | libxml.sax.js:7:22:7:42 | req.par ... e-xml") | libxml.sax.js:7:22:7:42 | req.par ... e-xml") | A $@ is parsed as XML without guarding against uncontrolled entity expansion. | libxml.sax.js:7:22:7:42 | req.par ... e-xml") | user-provided value |
-| libxml.saxpush.js:7:15:7:35 | req.par ... e-xml") | libxml.saxpush.js:7:15:7:35 | req.par ... e-xml") | libxml.saxpush.js:7:15:7:35 | req.par ... e-xml") | A $@ is parsed as XML without guarding against uncontrolled entity expansion. | libxml.saxpush.js:7:15:7:35 | req.par ... e-xml") | user-provided value |
+| libxml.sax.js:6:22:6:42 | req.par ... e-xml") | libxml.sax.js:6:22:6:42 | req.par ... e-xml") | libxml.sax.js:6:22:6:42 | req.par ... e-xml") | A $@ is parsed as XML without guarding against uncontrolled entity expansion. | libxml.sax.js:6:22:6:42 | req.par ... e-xml") | user-provided value |
+| libxml.saxpush.js:6:15:6:35 | req.par ... e-xml") | libxml.saxpush.js:6:15:6:35 | req.par ... e-xml") | libxml.saxpush.js:6:15:6:35 | req.par ... e-xml") | A $@ is parsed as XML without guarding against uncontrolled entity expansion. | libxml.saxpush.js:6:15:6:35 | req.par ... e-xml") | user-provided value |
diff --git a/javascript/ql/test/query-tests/Security/CWE-776/expat.js b/javascript/ql/test/query-tests/Security/CWE-776/expat.js
index 580674ce8ed0..89e4d6c29ab1 100644
--- a/javascript/ql/test/query-tests/Security/CWE-776/expat.js
+++ b/javascript/ql/test/query-tests/Security/CWE-776/expat.js
@@ -2,7 +2,6 @@ const express = require('express');
const expat = require('node-expat');
express().get('/some/path', function(req) {
- // NOT OK: expat expands internal entities by default
var parser = new expat.Parser();
- parser.write(req.param("some-xml"));
+ parser.write(req.param("some-xml")); // NOT OK: expat expands internal entities by default
});
diff --git a/javascript/ql/test/query-tests/Security/CWE-776/libxml.sax.js b/javascript/ql/test/query-tests/Security/CWE-776/libxml.sax.js
index 3ea44a1f236b..2c837c750d32 100644
--- a/javascript/ql/test/query-tests/Security/CWE-776/libxml.sax.js
+++ b/javascript/ql/test/query-tests/Security/CWE-776/libxml.sax.js
@@ -2,7 +2,6 @@ const express = require('express');
const libxmljs = require('libxmljs');
express().get('/some/path', function(req) {
- // NOT OK: the SAX parser expands external entities by default
const parser = new libxmljs.SaxParser();
- parser.parseString(req.param("some-xml"));
+ parser.parseString(req.param("some-xml")); // NOT OK: the SAX parser expands external entities by default
});
diff --git a/javascript/ql/test/query-tests/Security/CWE-776/libxml.saxpush.js b/javascript/ql/test/query-tests/Security/CWE-776/libxml.saxpush.js
index 127c92feddbf..5b5fef8a6aef 100644
--- a/javascript/ql/test/query-tests/Security/CWE-776/libxml.saxpush.js
+++ b/javascript/ql/test/query-tests/Security/CWE-776/libxml.saxpush.js
@@ -2,7 +2,6 @@ const express = require('express');
const libxmljs = require('libxmljs');
express().get('/some/path', function(req) {
- // NOT OK: the SAX parser expands external entities by default
const parser = new libxmljs.SaxPushParser();
- parser.push(req.param("some-xml"));
+ parser.push(req.param("some-xml")); // NOT OK: the SAX parser expands external entities by default
});
diff --git a/javascript/ql/test/query-tests/Security/CWE-798/HardcodedCredentials.js b/javascript/ql/test/query-tests/Security/CWE-798/HardcodedCredentials.js
index c72a4e16ccd4..a6b3d4a3baf4 100644
--- a/javascript/ql/test/query-tests/Security/CWE-798/HardcodedCredentials.js
+++ b/javascript/ql/test/query-tests/Security/CWE-798/HardcodedCredentials.js
@@ -2,12 +2,12 @@
const pg = require('pg');
const client = new pg.Client({
- user: 'dbuser',
+ user: 'dbuser', // NOT OK
host: 'database.server.com',
database: 'mydb',
- password: 'abcdefgh',
+ password: 'abcdefgh', // NOT OK
port: 3211,
- }); // NOT OK
+ });
client.connect();
})();
@@ -26,8 +26,8 @@
basicAuth({users: { 'admin': 'abcdefgh' }}); // NOT OK
var users = {};
- users['unknown-admin-name'] = 'abcdefgh';
- basicAuth({users: users}) // NOT OK
+ users['unknown-admin-name'] = 'abcdefgh'; // NOT OK
+ basicAuth({users: users});
})();
(function() {
@@ -43,26 +43,26 @@
var config = new AWS.Config();
config.update({ accessKeyId: 'username', secretAccessKey: 'abcdefgh'}); // NOT OK
var o = {};
- o.secretAccessKey = 'abcdefgh';
- config.update(o); // NOT OK
+ o.secretAccessKey = 'abcdefgh'; // NOT OK
+ config.update(o);
})();
(function() {
var request = require('request');
request.get(url).auth('username', 'abcdefgh'); // NOT OK
- request.get(url, { // NOT OK
+ request.get(url, {
'auth': {
- 'user': 'username',
- 'pass': 'abcdefgh'
+ 'user': 'username', // NOT OK
+ 'pass': 'abcdefgh' // NOT OK
}
});
request.get(url).auth(null, null, _, 'bearerToken'); // NOT OK
- request.get(url, { // NOT OK
+ request.get(url, {
'auth': {
- 'bearer': 'bearerToken'
+ 'bearer': 'bearerToken' // NOT OK
}
});
@@ -70,10 +70,10 @@
request.head(url).auth('username', 'abcdefgh'); // NOT OK
request(url).auth('username', 'abcdefgh'); // NOT OK
- request(url, { // NOT OK
+ request(url, {
'auth': {
- 'user': 'username',
- 'pass': 'abcdefgh'
+ 'user': 'username', // NOT OK
+ 'pass': 'abcdefgh' // NOT OK
}
});
})();
@@ -94,31 +94,31 @@
(function() {
var pkgcloud = require('pkgcloud');
- pkgcloud.compute.createClient({ // NOT OK
- account: 'x1',
- keyId: 'x2',
- storageAccount: 'x3',
- username: 'x4',
- key: 'abcdefgh',
- apiKey: 'abcdefgh',
- storageAccessKey: 'abcdefgh',
- password: 'abcdefgh',
- token: 'abcdefgh'
+ pkgcloud.compute.createClient({
+ account: 'x1', // NOT OK
+ keyId: 'x2',// NOT OK
+ storageAccount: 'x3', // NOT OK
+ username: 'x4', // NOT OK
+ key: 'abcdefgh', // NOT OK
+ apiKey: 'abcdefgh', // NOT OK
+ storageAccessKey: 'abcdefgh', // NOT OK
+ password: 'abcdefgh', // NOT OK
+ token: 'abcdefgh' // NOT OK
});
pkgcloud.compute.createClient({ // OK
INNOCENT_DATA: '42'
});
- pkgcloud.providers.SOME_PROVIDER.compute.createClient({ // NOT OK
- username: 'x5',
- password: 'abcdefgh'
+ pkgcloud.providers.SOME_PROVIDER.compute.createClient({
+ username: 'x5', // NOT OK
+ password: 'abcdefgh' // NOT OK
});
pkgcloud.UNKNOWN_SERVICE.createClient({ // OK
username: 'x6',
password: 'abcdefgh'
});
- pkgcloud.providers.SOME_PROVIDER.UNKNOWN_SERVICE.createClient({ // OK
- username: 'x7',
- password: 'abcdefgh'
+ pkgcloud.providers.SOME_PROVIDER.UNKNOWN_SERVICE.createClient({
+ username: 'x7', // OK
+ password: 'abcdefgh' // OK
});
pkgcloud.compute.createClient({ // OK
username: process.env.USERNAME,
diff --git a/javascript/ql/test/query-tests/Security/CWE-807/ConditionalBypass.expected b/javascript/ql/test/query-tests/Security/CWE-807/ConditionalBypass.expected
index ff45448452c3..71a36a5675e8 100644
--- a/javascript/ql/test/query-tests/Security/CWE-807/ConditionalBypass.expected
+++ b/javascript/ql/test/query-tests/Security/CWE-807/ConditionalBypass.expected
@@ -2,113 +2,113 @@ nodes
| tst.js:9:8:9:26 | req.params.shutDown |
| tst.js:9:8:9:26 | req.params.shutDown |
| tst.js:9:8:9:26 | req.params.shutDown |
-| tst.js:14:9:14:19 | req.cookies |
-| tst.js:14:9:14:19 | req.cookies |
-| tst.js:14:9:14:30 | req.coo ... inThing |
-| tst.js:14:9:14:30 | req.coo ... inThing |
-| tst.js:30:9:30:37 | v3 |
-| tst.js:30:14:30:37 | id(req. ... okieId) |
-| tst.js:30:17:30:27 | req.cookies |
-| tst.js:30:17:30:27 | req.cookies |
-| tst.js:30:17:30:36 | req.cookies.cookieId |
-| tst.js:31:9:31:10 | v3 |
-| tst.js:31:9:31:10 | v3 |
-| tst.js:37:13:37:23 | req.cookies |
-| tst.js:37:13:37:23 | req.cookies |
-| tst.js:37:13:37:32 | req.cookies.cookieId |
-| tst.js:37:13:37:32 | req.cookies.cookieId |
-| tst.js:43:9:43:19 | req.cookies |
-| tst.js:43:9:43:19 | req.cookies |
-| tst.js:43:9:43:28 | req.cookies.cookieId |
-| tst.js:43:9:43:28 | req.cookies.cookieId |
-| tst.js:50:8:50:23 | req.params.login |
-| tst.js:50:8:50:23 | req.params.login |
-| tst.js:50:8:50:23 | req.params.login |
-| tst.js:65:8:65:23 | req.params.login |
-| tst.js:65:8:65:23 | req.params.login |
-| tst.js:65:8:65:23 | req.params.login |
-| tst.js:70:9:70:19 | req.cookies |
-| tst.js:70:9:70:19 | req.cookies |
-| tst.js:70:9:70:28 | req.cookies.cookieId |
-| tst.js:70:9:70:28 | req.cookies.cookieId |
-| tst.js:70:34:70:53 | req.params.requestId |
-| tst.js:70:34:70:53 | req.params.requestId |
-| tst.js:70:34:70:53 | req.params.requestId |
-| tst.js:75:14:75:24 | req.cookies |
-| tst.js:75:14:75:24 | req.cookies |
-| tst.js:75:14:75:33 | req.cookies.cookieId |
-| tst.js:75:14:75:33 | req.cookies.cookieId |
-| tst.js:75:39:75:58 | req.params.requestId |
-| tst.js:75:39:75:58 | req.params.requestId |
-| tst.js:75:39:75:58 | req.params.requestId |
-| tst.js:90:9:90:19 | req.cookies |
-| tst.js:90:9:90:19 | req.cookies |
-| tst.js:90:9:90:28 | req.cookies.cookieId |
-| tst.js:90:9:90:28 | req.cookies.cookieId |
-| tst.js:90:9:90:41 | req.coo ... secret" |
-| tst.js:90:9:90:41 | req.coo ... secret" |
-| tst.js:104:10:104:17 | req.body |
-| tst.js:104:10:104:17 | req.body |
-| tst.js:104:10:104:17 | req.body |
-| tst.js:111:13:111:32 | req.query.vulnerable |
-| tst.js:111:13:111:32 | req.query.vulnerable |
-| tst.js:111:13:111:32 | req.query.vulnerable |
-| tst.js:118:13:118:32 | req.query.vulnerable |
-| tst.js:118:13:118:32 | req.query.vulnerable |
-| tst.js:118:13:118:32 | req.query.vulnerable |
-| tst.js:126:13:126:32 | req.query.vulnerable |
-| tst.js:126:13:126:32 | req.query.vulnerable |
-| tst.js:126:13:126:32 | req.query.vulnerable |
+| tst.js:13:9:13:19 | req.cookies |
+| tst.js:13:9:13:19 | req.cookies |
+| tst.js:13:9:13:30 | req.coo ... inThing |
+| tst.js:13:9:13:30 | req.coo ... inThing |
+| tst.js:27:9:27:37 | v3 |
+| tst.js:27:14:27:37 | id(req. ... okieId) |
+| tst.js:27:17:27:27 | req.cookies |
+| tst.js:27:17:27:27 | req.cookies |
+| tst.js:27:17:27:36 | req.cookies.cookieId |
+| tst.js:28:9:28:10 | v3 |
+| tst.js:28:9:28:10 | v3 |
+| tst.js:33:13:33:23 | req.cookies |
+| tst.js:33:13:33:23 | req.cookies |
+| tst.js:33:13:33:32 | req.cookies.cookieId |
+| tst.js:33:13:33:32 | req.cookies.cookieId |
+| tst.js:38:9:38:19 | req.cookies |
+| tst.js:38:9:38:19 | req.cookies |
+| tst.js:38:9:38:28 | req.cookies.cookieId |
+| tst.js:38:9:38:28 | req.cookies.cookieId |
+| tst.js:44:8:44:23 | req.params.login |
+| tst.js:44:8:44:23 | req.params.login |
+| tst.js:44:8:44:23 | req.params.login |
+| tst.js:57:8:57:23 | req.params.login |
+| tst.js:57:8:57:23 | req.params.login |
+| tst.js:57:8:57:23 | req.params.login |
+| tst.js:61:9:61:19 | req.cookies |
+| tst.js:61:9:61:19 | req.cookies |
+| tst.js:61:9:61:28 | req.cookies.cookieId |
+| tst.js:61:9:61:28 | req.cookies.cookieId |
+| tst.js:61:34:61:53 | req.params.requestId |
+| tst.js:61:34:61:53 | req.params.requestId |
+| tst.js:61:34:61:53 | req.params.requestId |
+| tst.js:65:14:65:24 | req.cookies |
+| tst.js:65:14:65:24 | req.cookies |
+| tst.js:65:14:65:33 | req.cookies.cookieId |
+| tst.js:65:14:65:33 | req.cookies.cookieId |
+| tst.js:65:39:65:58 | req.params.requestId |
+| tst.js:65:39:65:58 | req.params.requestId |
+| tst.js:65:39:65:58 | req.params.requestId |
+| tst.js:78:9:78:19 | req.cookies |
+| tst.js:78:9:78:19 | req.cookies |
+| tst.js:78:9:78:28 | req.cookies.cookieId |
+| tst.js:78:9:78:28 | req.cookies.cookieId |
+| tst.js:78:9:78:41 | req.coo ... secret" |
+| tst.js:78:9:78:41 | req.coo ... secret" |
+| tst.js:91:10:91:17 | req.body |
+| tst.js:91:10:91:17 | req.body |
+| tst.js:91:10:91:17 | req.body |
+| tst.js:98:13:98:32 | req.query.vulnerable |
+| tst.js:98:13:98:32 | req.query.vulnerable |
+| tst.js:98:13:98:32 | req.query.vulnerable |
+| tst.js:105:13:105:32 | req.query.vulnerable |
+| tst.js:105:13:105:32 | req.query.vulnerable |
+| tst.js:105:13:105:32 | req.query.vulnerable |
+| tst.js:113:13:113:32 | req.query.vulnerable |
+| tst.js:113:13:113:32 | req.query.vulnerable |
+| tst.js:113:13:113:32 | req.query.vulnerable |
edges
| tst.js:9:8:9:26 | req.params.shutDown | tst.js:9:8:9:26 | req.params.shutDown |
-| tst.js:14:9:14:19 | req.cookies | tst.js:14:9:14:30 | req.coo ... inThing |
-| tst.js:14:9:14:19 | req.cookies | tst.js:14:9:14:30 | req.coo ... inThing |
-| tst.js:14:9:14:19 | req.cookies | tst.js:14:9:14:30 | req.coo ... inThing |
-| tst.js:14:9:14:19 | req.cookies | tst.js:14:9:14:30 | req.coo ... inThing |
-| tst.js:30:9:30:37 | v3 | tst.js:31:9:31:10 | v3 |
-| tst.js:30:9:30:37 | v3 | tst.js:31:9:31:10 | v3 |
-| tst.js:30:14:30:37 | id(req. ... okieId) | tst.js:30:9:30:37 | v3 |
-| tst.js:30:17:30:27 | req.cookies | tst.js:30:17:30:36 | req.cookies.cookieId |
-| tst.js:30:17:30:27 | req.cookies | tst.js:30:17:30:36 | req.cookies.cookieId |
-| tst.js:30:17:30:36 | req.cookies.cookieId | tst.js:30:14:30:37 | id(req. ... okieId) |
-| tst.js:37:13:37:23 | req.cookies | tst.js:37:13:37:32 | req.cookies.cookieId |
-| tst.js:37:13:37:23 | req.cookies | tst.js:37:13:37:32 | req.cookies.cookieId |
-| tst.js:37:13:37:23 | req.cookies | tst.js:37:13:37:32 | req.cookies.cookieId |
-| tst.js:37:13:37:23 | req.cookies | tst.js:37:13:37:32 | req.cookies.cookieId |
-| tst.js:43:9:43:19 | req.cookies | tst.js:43:9:43:28 | req.cookies.cookieId |
-| tst.js:43:9:43:19 | req.cookies | tst.js:43:9:43:28 | req.cookies.cookieId |
-| tst.js:43:9:43:19 | req.cookies | tst.js:43:9:43:28 | req.cookies.cookieId |
-| tst.js:43:9:43:19 | req.cookies | tst.js:43:9:43:28 | req.cookies.cookieId |
-| tst.js:50:8:50:23 | req.params.login | tst.js:50:8:50:23 | req.params.login |
-| tst.js:65:8:65:23 | req.params.login | tst.js:65:8:65:23 | req.params.login |
-| tst.js:70:9:70:19 | req.cookies | tst.js:70:9:70:28 | req.cookies.cookieId |
-| tst.js:70:9:70:19 | req.cookies | tst.js:70:9:70:28 | req.cookies.cookieId |
-| tst.js:70:9:70:19 | req.cookies | tst.js:70:9:70:28 | req.cookies.cookieId |
-| tst.js:70:9:70:19 | req.cookies | tst.js:70:9:70:28 | req.cookies.cookieId |
-| tst.js:70:34:70:53 | req.params.requestId | tst.js:70:34:70:53 | req.params.requestId |
-| tst.js:75:14:75:24 | req.cookies | tst.js:75:14:75:33 | req.cookies.cookieId |
-| tst.js:75:14:75:24 | req.cookies | tst.js:75:14:75:33 | req.cookies.cookieId |
-| tst.js:75:14:75:24 | req.cookies | tst.js:75:14:75:33 | req.cookies.cookieId |
-| tst.js:75:14:75:24 | req.cookies | tst.js:75:14:75:33 | req.cookies.cookieId |
-| tst.js:75:39:75:58 | req.params.requestId | tst.js:75:39:75:58 | req.params.requestId |
-| tst.js:90:9:90:19 | req.cookies | tst.js:90:9:90:28 | req.cookies.cookieId |
-| tst.js:90:9:90:19 | req.cookies | tst.js:90:9:90:28 | req.cookies.cookieId |
-| tst.js:90:9:90:19 | req.cookies | tst.js:90:9:90:28 | req.cookies.cookieId |
-| tst.js:90:9:90:19 | req.cookies | tst.js:90:9:90:28 | req.cookies.cookieId |
-| tst.js:90:9:90:28 | req.cookies.cookieId | tst.js:90:9:90:41 | req.coo ... secret" |
-| tst.js:90:9:90:28 | req.cookies.cookieId | tst.js:90:9:90:41 | req.coo ... secret" |
-| tst.js:104:10:104:17 | req.body | tst.js:104:10:104:17 | req.body |
-| tst.js:111:13:111:32 | req.query.vulnerable | tst.js:111:13:111:32 | req.query.vulnerable |
-| tst.js:118:13:118:32 | req.query.vulnerable | tst.js:118:13:118:32 | req.query.vulnerable |
-| tst.js:126:13:126:32 | req.query.vulnerable | tst.js:126:13:126:32 | req.query.vulnerable |
+| tst.js:13:9:13:19 | req.cookies | tst.js:13:9:13:30 | req.coo ... inThing |
+| tst.js:13:9:13:19 | req.cookies | tst.js:13:9:13:30 | req.coo ... inThing |
+| tst.js:13:9:13:19 | req.cookies | tst.js:13:9:13:30 | req.coo ... inThing |
+| tst.js:13:9:13:19 | req.cookies | tst.js:13:9:13:30 | req.coo ... inThing |
+| tst.js:27:9:27:37 | v3 | tst.js:28:9:28:10 | v3 |
+| tst.js:27:9:27:37 | v3 | tst.js:28:9:28:10 | v3 |
+| tst.js:27:14:27:37 | id(req. ... okieId) | tst.js:27:9:27:37 | v3 |
+| tst.js:27:17:27:27 | req.cookies | tst.js:27:17:27:36 | req.cookies.cookieId |
+| tst.js:27:17:27:27 | req.cookies | tst.js:27:17:27:36 | req.cookies.cookieId |
+| tst.js:27:17:27:36 | req.cookies.cookieId | tst.js:27:14:27:37 | id(req. ... okieId) |
+| tst.js:33:13:33:23 | req.cookies | tst.js:33:13:33:32 | req.cookies.cookieId |
+| tst.js:33:13:33:23 | req.cookies | tst.js:33:13:33:32 | req.cookies.cookieId |
+| tst.js:33:13:33:23 | req.cookies | tst.js:33:13:33:32 | req.cookies.cookieId |
+| tst.js:33:13:33:23 | req.cookies | tst.js:33:13:33:32 | req.cookies.cookieId |
+| tst.js:38:9:38:19 | req.cookies | tst.js:38:9:38:28 | req.cookies.cookieId |
+| tst.js:38:9:38:19 | req.cookies | tst.js:38:9:38:28 | req.cookies.cookieId |
+| tst.js:38:9:38:19 | req.cookies | tst.js:38:9:38:28 | req.cookies.cookieId |
+| tst.js:38:9:38:19 | req.cookies | tst.js:38:9:38:28 | req.cookies.cookieId |
+| tst.js:44:8:44:23 | req.params.login | tst.js:44:8:44:23 | req.params.login |
+| tst.js:57:8:57:23 | req.params.login | tst.js:57:8:57:23 | req.params.login |
+| tst.js:61:9:61:19 | req.cookies | tst.js:61:9:61:28 | req.cookies.cookieId |
+| tst.js:61:9:61:19 | req.cookies | tst.js:61:9:61:28 | req.cookies.cookieId |
+| tst.js:61:9:61:19 | req.cookies | tst.js:61:9:61:28 | req.cookies.cookieId |
+| tst.js:61:9:61:19 | req.cookies | tst.js:61:9:61:28 | req.cookies.cookieId |
+| tst.js:61:34:61:53 | req.params.requestId | tst.js:61:34:61:53 | req.params.requestId |
+| tst.js:65:14:65:24 | req.cookies | tst.js:65:14:65:33 | req.cookies.cookieId |
+| tst.js:65:14:65:24 | req.cookies | tst.js:65:14:65:33 | req.cookies.cookieId |
+| tst.js:65:14:65:24 | req.cookies | tst.js:65:14:65:33 | req.cookies.cookieId |
+| tst.js:65:14:65:24 | req.cookies | tst.js:65:14:65:33 | req.cookies.cookieId |
+| tst.js:65:39:65:58 | req.params.requestId | tst.js:65:39:65:58 | req.params.requestId |
+| tst.js:78:9:78:19 | req.cookies | tst.js:78:9:78:28 | req.cookies.cookieId |
+| tst.js:78:9:78:19 | req.cookies | tst.js:78:9:78:28 | req.cookies.cookieId |
+| tst.js:78:9:78:19 | req.cookies | tst.js:78:9:78:28 | req.cookies.cookieId |
+| tst.js:78:9:78:19 | req.cookies | tst.js:78:9:78:28 | req.cookies.cookieId |
+| tst.js:78:9:78:28 | req.cookies.cookieId | tst.js:78:9:78:41 | req.coo ... secret" |
+| tst.js:78:9:78:28 | req.cookies.cookieId | tst.js:78:9:78:41 | req.coo ... secret" |
+| tst.js:91:10:91:17 | req.body | tst.js:91:10:91:17 | req.body |
+| tst.js:98:13:98:32 | req.query.vulnerable | tst.js:98:13:98:32 | req.query.vulnerable |
+| tst.js:105:13:105:32 | req.query.vulnerable | tst.js:105:13:105:32 | req.query.vulnerable |
+| tst.js:113:13:113:32 | req.query.vulnerable | tst.js:113:13:113:32 | req.query.vulnerable |
#select
-| tst.js:9:8:9:26 | req.params.shutDown | tst.js:9:8:9:26 | req.params.shutDown | tst.js:9:8:9:26 | req.params.shutDown | This condition guards a sensitive $@, but $@ controls it. | tst.js:11:9:11:22 | process.exit() | action | tst.js:9:8:9:26 | req.params.shutDown | a user-provided value |
-| tst.js:14:9:14:30 | req.coo ... inThing | tst.js:14:9:14:19 | req.cookies | tst.js:14:9:14:30 | req.coo ... inThing | This condition guards a sensitive $@, but $@ controls it. | tst.js:16:9:16:17 | o.login() | action | tst.js:14:9:14:19 | req.cookies | a user-provided value |
-| tst.js:31:9:31:10 | v3 | tst.js:30:17:30:27 | req.cookies | tst.js:31:9:31:10 | v3 | This condition guards a sensitive $@, but $@ controls it. | tst.js:33:9:33:22 | process.exit() | action | tst.js:30:17:30:27 | req.cookies | a user-provided value |
-| tst.js:37:13:37:32 | req.cookies.cookieId | tst.js:37:13:37:23 | req.cookies | tst.js:37:13:37:32 | req.cookies.cookieId | This condition guards a sensitive $@, but $@ controls it. | tst.js:39:13:39:26 | process.exit() | action | tst.js:37:13:37:23 | req.cookies | a user-provided value |
-| tst.js:43:9:43:28 | req.cookies.cookieId | tst.js:43:9:43:19 | req.cookies | tst.js:43:9:43:28 | req.cookies.cookieId | This condition guards a sensitive $@, but $@ controls it. | tst.js:46:13:46:26 | process.exit() | action | tst.js:43:9:43:19 | req.cookies | a user-provided value |
-| tst.js:50:8:50:23 | req.params.login | tst.js:50:8:50:23 | req.params.login | tst.js:50:8:50:23 | req.params.login | This condition guards a sensitive $@, but $@ controls it. | tst.js:54:9:54:15 | login() | action | tst.js:50:8:50:23 | req.params.login | a user-provided value |
-| tst.js:65:8:65:23 | req.params.login | tst.js:65:8:65:23 | req.params.login | tst.js:65:8:65:23 | req.params.login | This condition guards a sensitive $@, but $@ controls it. | tst.js:67:9:67:15 | login() | action | tst.js:65:8:65:23 | req.params.login | a user-provided value |
-| tst.js:90:9:90:41 | req.coo ... secret" | tst.js:90:9:90:19 | req.cookies | tst.js:90:9:90:41 | req.coo ... secret" | This condition guards a sensitive $@, but $@ controls it. | tst.js:92:9:92:22 | process.exit() | action | tst.js:90:9:90:19 | req.cookies | a user-provided value |
-| tst.js:111:13:111:32 | req.query.vulnerable | tst.js:111:13:111:32 | req.query.vulnerable | tst.js:111:13:111:32 | req.query.vulnerable | This condition guards a sensitive $@, but $@ controls it. | tst.js:114:9:114:16 | verify() | action | tst.js:111:13:111:32 | req.query.vulnerable | a user-provided value |
-| tst.js:118:13:118:32 | req.query.vulnerable | tst.js:118:13:118:32 | req.query.vulnerable | tst.js:118:13:118:32 | req.query.vulnerable | This condition guards a sensitive $@, but $@ controls it. | tst.js:121:13:121:20 | verify() | action | tst.js:118:13:118:32 | req.query.vulnerable | a user-provided value |
+| tst.js:9:8:9:26 | req.params.shutDown | tst.js:9:8:9:26 | req.params.shutDown | tst.js:9:8:9:26 | req.params.shutDown | This condition guards a sensitive $@, but $@ controls it. | tst.js:10:9:10:22 | process.exit() | action | tst.js:9:8:9:26 | req.params.shutDown | a user-provided value |
+| tst.js:13:9:13:30 | req.coo ... inThing | tst.js:13:9:13:19 | req.cookies | tst.js:13:9:13:30 | req.coo ... inThing | This condition guards a sensitive $@, but $@ controls it. | tst.js:14:9:14:17 | o.login() | action | tst.js:13:9:13:19 | req.cookies | a user-provided value |
+| tst.js:28:9:28:10 | v3 | tst.js:27:17:27:27 | req.cookies | tst.js:28:9:28:10 | v3 | This condition guards a sensitive $@, but $@ controls it. | tst.js:29:9:29:22 | process.exit() | action | tst.js:27:17:27:27 | req.cookies | a user-provided value |
+| tst.js:33:13:33:32 | req.cookies.cookieId | tst.js:33:13:33:23 | req.cookies | tst.js:33:13:33:32 | req.cookies.cookieId | This condition guards a sensitive $@, but $@ controls it. | tst.js:34:13:34:26 | process.exit() | action | tst.js:33:13:33:23 | req.cookies | a user-provided value |
+| tst.js:38:9:38:28 | req.cookies.cookieId | tst.js:38:9:38:19 | req.cookies | tst.js:38:9:38:28 | req.cookies.cookieId | This condition guards a sensitive $@, but $@ controls it. | tst.js:40:13:40:26 | process.exit() | action | tst.js:38:9:38:19 | req.cookies | a user-provided value |
+| tst.js:44:8:44:23 | req.params.login | tst.js:44:8:44:23 | req.params.login | tst.js:44:8:44:23 | req.params.login | This condition guards a sensitive $@, but $@ controls it. | tst.js:47:9:47:15 | login() | action | tst.js:44:8:44:23 | req.params.login | a user-provided value |
+| tst.js:57:8:57:23 | req.params.login | tst.js:57:8:57:23 | req.params.login | tst.js:57:8:57:23 | req.params.login | This condition guards a sensitive $@, but $@ controls it. | tst.js:58:9:58:15 | login() | action | tst.js:57:8:57:23 | req.params.login | a user-provided value |
+| tst.js:78:9:78:41 | req.coo ... secret" | tst.js:78:9:78:19 | req.cookies | tst.js:78:9:78:41 | req.coo ... secret" | This condition guards a sensitive $@, but $@ controls it. | tst.js:79:9:79:22 | process.exit() | action | tst.js:78:9:78:19 | req.cookies | a user-provided value |
+| tst.js:98:13:98:32 | req.query.vulnerable | tst.js:98:13:98:32 | req.query.vulnerable | tst.js:98:13:98:32 | req.query.vulnerable | This condition guards a sensitive $@, but $@ controls it. | tst.js:101:9:101:16 | verify() | action | tst.js:98:13:98:32 | req.query.vulnerable | a user-provided value |
+| tst.js:105:13:105:32 | req.query.vulnerable | tst.js:105:13:105:32 | req.query.vulnerable | tst.js:105:13:105:32 | req.query.vulnerable | This condition guards a sensitive $@, but $@ controls it. | tst.js:108:13:108:20 | verify() | action | tst.js:105:13:105:32 | req.query.vulnerable | a user-provided value |
diff --git a/javascript/ql/test/query-tests/Security/CWE-807/DifferentKindsComparisonBypass.expected b/javascript/ql/test/query-tests/Security/CWE-807/DifferentKindsComparisonBypass.expected
index 9bb73d79a82c..e6529de1c833 100644
--- a/javascript/ql/test/query-tests/Security/CWE-807/DifferentKindsComparisonBypass.expected
+++ b/javascript/ql/test/query-tests/Security/CWE-807/DifferentKindsComparisonBypass.expected
@@ -1,6 +1,6 @@
| tst-different-kinds-comparison-bypass.js:7:5:7:42 | req.que ... .userId | This comparison of $@ and $@ is a potential security risk since it is controlled by the user. | tst-different-kinds-comparison-bypass.js:7:5:7:20 | req.query.userId | req.query.userId | tst-different-kinds-comparison-bypass.js:7:25:7:35 | req.cookies | req.cookies |
| tst-different-kinds-comparison-bypass.js:11:5:11:23 | req.url == req.body | This comparison of $@ and $@ is a potential security risk since it is controlled by the user. | tst-different-kinds-comparison-bypass.js:11:5:11:11 | req.url | req.url | tst-different-kinds-comparison-bypass.js:11:16:11:23 | req.body | req.body |
| tst-different-kinds-comparison-bypass.js:16:9:16:14 | a == b | This comparison of $@ and $@ is a potential security risk since it is controlled by the user. | tst-different-kinds-comparison-bypass.js:13:11:13:26 | req.query.userId | req.query.userId | tst-different-kinds-comparison-bypass.js:13:29:13:39 | req.cookies | req.cookies |
-| tst.js:70:9:70:53 | req.coo ... questId | This comparison of $@ and $@ is a potential security risk since it is controlled by the user. | tst.js:70:9:70:19 | req.cookies | req.cookies | tst.js:70:34:70:53 | req.params.requestId | req.params.requestId |
-| tst.js:75:14:75:58 | req.coo ... questId | This comparison of $@ and $@ is a potential security risk since it is controlled by the user. | tst.js:75:14:75:24 | req.cookies | req.cookies | tst.js:75:39:75:58 | req.params.requestId | req.params.requestId |
-| tst.js:82:16:82:22 | p === q | This comparison of $@ and $@ is a potential security risk since it is controlled by the user. | tst.js:84:18:84:28 | req.cookies | req.cookies | tst.js:84:40:84:59 | req.params.requestId | req.params.requestId |
+| tst.js:61:9:61:53 | req.coo ... questId | This comparison of $@ and $@ is a potential security risk since it is controlled by the user. | tst.js:61:9:61:19 | req.cookies | req.cookies | tst.js:61:34:61:53 | req.params.requestId | req.params.requestId |
+| tst.js:65:14:65:58 | req.coo ... questId | This comparison of $@ and $@ is a potential security risk since it is controlled by the user. | tst.js:65:14:65:24 | req.cookies | req.cookies | tst.js:65:39:65:58 | req.params.requestId | req.params.requestId |
+| tst.js:71:16:71:22 | p === q | This comparison of $@ and $@ is a potential security risk since it is controlled by the user. | tst.js:73:18:73:28 | req.cookies | req.cookies | tst.js:73:40:73:59 | req.params.requestId | req.params.requestId |
diff --git a/javascript/ql/test/query-tests/Security/CWE-807/tst.js b/javascript/ql/test/query-tests/Security/CWE-807/tst.js
index aa00c47f1ebd..9fd7507b5682 100644
--- a/javascript/ql/test/query-tests/Security/CWE-807/tst.js
+++ b/javascript/ql/test/query-tests/Security/CWE-807/tst.js
@@ -6,18 +6,15 @@ app.get('/user/:id', function(req, res) {
// OK
process.exit();
- if(req.params.shutDown) {
- // NOT OK: depends on user input
+ if(req.params.shutDown) { // NOT OK: depends on user input
process.exit();
}
- if (req.cookies.loginThing) {
- // NOT OK: depends on user input
+ if (req.cookies.loginThing) { // NOT OK: depends on user input
o.login();
}
- if (req.cookies.loginThing) {
- // OK: not a sensitive action
+ if (req.cookies.loginThing) { // OK: not a sensitive action
o.getLogin();
}
@@ -28,67 +25,57 @@ app.get('/user/:id', function(req, res) {
return v;
}
var v3 = id(req.cookies.cookieId);
- if (v3) {
- // NOT OK, depends on user input
+ if (v3) { // NOT OK, depends on user input
process.exit();
}
if (otherCondition) {
- if (req.cookies.cookieId) {
- // NOT OK: depends on user input
+ if (req.cookies.cookieId) { // NOT OK: depends on user input
process.exit();
}
}
- if (req.cookies.cookieId) {
+ if (req.cookies.cookieId) { // OK: but flagged anyway due to plain dominance analysis [INCONSISTENCY]
if (otherCondition) {
- // OK: but flagged anyway due to plain dominance analysis
process.exit();
}
}
- if(req.params.login) {
+ if(req.params.login) { // NOT OK: depends on user input
} else {
- // NOT OK: depends on user input
login()
}
- if(req.params.login && somethingElse) {
+ if(req.params.login && somethingElse) { // OK: depends on something else
} else {
- // OK: depends on something else
login()
}
- if(req.params.login && somethingElse) {
- // NOT OK: depends on user input
+ if(req.params.login && somethingElse) { // NOT OK: depends on user input
login()
}
- if (req.cookies.cookieId === req.params.requestId) {
- // NOT OK: depends on user input
+ if (req.cookies.cookieId === req.params.requestId) { // NOT OK: depends on user input
process.exit();
}
- var v1 = req.cookies.cookieId === req.params.requestId;
+ var v1 = req.cookies.cookieId === req.params.requestId; // NOT OK: depends on user input
if (v1) {
- // NOT OK: depends on user input
process.exit();
}
function cmp(p, q) {
return p === q;
}
- var v2 = cmp(req.cookies.cookieId, req.params.requestId);
+ var v2 = cmp(req.cookies.cookieId, req.params.requestId); // NOT OK, but not detected due to flow limitations [INCONSISTENCY]
if (v2) {
- // NOT OK, but not detected due to flow limitations
process.exit();
}
- if (req.cookies.cookieId === "secret") {
- // NOT OK: depends on user input
+ if (req.cookies.cookieId === "secret") { // NOT OK: depends on user input
process.exit();
}
diff --git a/javascript/ql/test/query-tests/Security/CWE-834/LoopBoundInjectionBad.js b/javascript/ql/test/query-tests/Security/CWE-834/LoopBoundInjectionBad.js
index 734ed5065431..bca6567b4f5e 100644
--- a/javascript/ql/test/query-tests/Security/CWE-834/LoopBoundInjectionBad.js
+++ b/javascript/ql/test/query-tests/Security/CWE-834/LoopBoundInjectionBad.js
@@ -35,9 +35,9 @@ function whileLoop(val) {
function useLengthIndirectly(val) {
var ret = [];
- var len = val.length;
+ var len = val.length; // NOT OK!
- for (var i = 0; i < len; i++) { // NOT OK!
+ for (var i = 0; i < len; i++) {
ret.push(val[i]);
}
}
diff --git a/javascript/ql/test/query-tests/Security/CWE-834/LoopBoundInjectionExitBad.js b/javascript/ql/test/query-tests/Security/CWE-834/LoopBoundInjectionExitBad.js
index 6f999c739377..3193a384aca2 100644
--- a/javascript/ql/test/query-tests/Security/CWE-834/LoopBoundInjectionExitBad.js
+++ b/javascript/ql/test/query-tests/Security/CWE-834/LoopBoundInjectionExitBad.js
@@ -56,8 +56,8 @@ function returns(val) {
}
}
-function lodashThrow(val) { // NOT OK!
- _.map(val, function (e) {
+function lodashThrow(val) {
+ _.map(val, function (e) { // NOT OK!
if (!e) {
try {
throw new Error(); // Does not prevent DoS.
diff --git a/javascript/ql/test/query-tests/Security/CWE-843/tst.js b/javascript/ql/test/query-tests/Security/CWE-843/tst.js
index 45753b8d8416..4f686b62e085 100644
--- a/javascript/ql/test/query-tests/Security/CWE-843/tst.js
+++ b/javascript/ql/test/query-tests/Security/CWE-843/tst.js
@@ -33,7 +33,7 @@ express().get('/some/path', function(req, res) {
foo.indexOf(); // OK
}
if (foo instanceof Array) {
- foo.indexOf(); // OK, but still flagged
+ foo.indexOf(); // OK, but still flagged [INCONSISTENCY]
}
(foo + f()).indexOf(); // OK
diff --git a/javascript/ql/test/query-tests/Security/CWE-918/tst.js b/javascript/ql/test/query-tests/Security/CWE-918/tst.js
index 53a1ce5477cf..0228280e081d 100644
--- a/javascript/ql/test/query-tests/Security/CWE-918/tst.js
+++ b/javascript/ql/test/query-tests/Security/CWE-918/tst.js
@@ -20,8 +20,8 @@ var server = http.createServer(function(req, res) {
request.get(tainted); // NOT OK
var options = {};
- options.url = tainted;
- request(options); // NOT OK
+ options.url = tainted; // NOT OK
+ request(options);
request("http://" + tainted); // NOT OK
@@ -44,7 +44,7 @@ var server = http.createServer(function(req, res) {
request('http://example.com/' + base + '/' + tainted); // NOT OK
- request('http://example.com/' + base + ('/' + tainted)); // NOT OK - but not flagged
+ request('http://example.com/' + base + ('/' + tainted)); // NOT OK - but not flagged [INCONSISTENCY]
request(`http://example.com/?${base}/${tainted}`); // OK
diff --git a/javascript/ql/test/testUtilities/ConsistencyChecking.qll b/javascript/ql/test/testUtilities/ConsistencyChecking.qll
index f830c134b941..cd02a9986492 100644
--- a/javascript/ql/test/testUtilities/ConsistencyChecking.qll
+++ b/javascript/ql/test/testUtilities/ConsistencyChecking.qll
@@ -25,6 +25,20 @@ abstract class ConsistencyConfiguration extends string {
File getAFile() { none() }
}
+/**
+ * A string that either equals a `ConsistencyConfiguration`, or the empty string if no such configuration exists.
+ *
+ * Is used internally to match a configuration or lack thereof.
+ */
+final private class Conf extends string {
+ Conf() {
+ this instanceof ConsistencyConfiguration
+ or
+ not exists(ConsistencyConfiguration c) and
+ this = ""
+ }
+}
+
/**
* A line-comment that asserts whether a result exists at that line or not.
* Can optionally include `[INCONSISTENCY]` to indicate that a consistency issue is expected at the location
@@ -54,22 +68,23 @@ private class AssertionComment extends LineComment {
private DataFlow::Node getASink() { exists(DataFlow::Configuration cfg | cfg.hasFlow(_, result)) }
/**
- * Gets all the alerts for consistency consistency checking.
+ * Gets all the alerts for consistency consistency checking from a configuration `conf`.
*/
-private DataFlow::Node alerts() {
- result = any(ConsistencyConfiguration res).getAnAlert()
+private DataFlow::Node alerts(Conf conf) {
+ result = any(ConsistencyConfiguration res | res = conf).getAnAlert()
or
not exists(ConsistencyConfiguration r) and
- result = getASink()
+ result = getASink() and
+ conf = ""
}
/**
- * Gets an alert in `file` at `line`.
+ * Gets an alert in `file` at `line` for configuration `conf`.
* The `line` can be either the first or the last line of the alert.
* And if no expression exists at `line`, then an alert on the next line is used.
*/
-private DataFlow::Node getAlert(File file, int line) {
- result = alerts() and
+private DataFlow::Node getAlert(File file, int line, Conf conf) {
+ result = alerts(conf) and
result.getFile() = file and
(result.hasLocationInfo(_, _, _, line, _) or result.hasLocationInfo(_, line, _, _, _))
or
@@ -77,7 +92,7 @@ private DataFlow::Node getAlert(File file, int line) {
not exists(Expr e |
e.getFile() = file and [e.getLocation().getStartLine(), e.getLocation().getEndLine()] = line
) and
- result = alerts() and
+ result = alerts(conf) and
result.getFile() = file and
result.hasLocationInfo(_, line + 1, _, _, _)
}
@@ -91,66 +106,70 @@ private AssertionComment getComment(File file, int line) {
}
/**
- * Holds if there is a false positive in `file` at `line`
+ * Holds if there is a false positive in `file` at `line` for configuration `conf`.
*/
-private predicate falsePositive(File file, int line, AssertionComment comment) {
- exists(getAlert(file, line)) and
+private predicate falsePositive(File file, int line, AssertionComment comment, Conf conf) {
+ exists(getAlert(file, line, conf)) and
comment = getComment(file, line) and
not comment.shouldHaveAlert()
}
/**
- * Holds if there is a false negative in `file` at `line`
+ * Holds if there is a false negative in `file` at `line` for configuration `conf`.
*/
-private predicate falseNegative(File file, int line, AssertionComment comment) {
- not exists(getAlert(file, line)) and
+private predicate falseNegative(File file, int line, AssertionComment comment, Conf conf) {
+ not exists(getAlert(file, line, conf)) and
comment = getComment(file, line) and
comment.shouldHaveAlert()
}
/**
- * Gets a file that should be included for consistency checking.
+ * Gets a file that should be included for consistency checking for configuration `conf`.
*/
-private File getATestFile() {
+private File getATestFile(string conf) {
not exists(any(ConsistencyConfiguration res).getAFile()) and
- result = any(LineComment comment).getFile()
+ result = any(LineComment comment).getFile() and
+ conf = ""
or
- result = any(ConsistencyConfiguration res).getAFile()
+ result = any(ConsistencyConfiguration res | res = conf).getAFile()
}
/**
- * Gets a description of the configuration that has a sink in `file` at `line`.
+ * Gets a description of the configuration that has a sink in `file` at `line` for configuration `conf`.
* Or the empty string
*/
bindingset[file, line]
-private string getSinkDescription(File file, int line) {
- not exists(DataFlow::Configuration c | c.hasFlow(_, getAlert(file, line))) and result = ""
+private string getSinkDescription(File file, int line, Conf conf) {
+ not exists(DataFlow::Configuration c | c.hasFlow(_, getAlert(file, line, conf))) and
+ result = ""
or
- exists(DataFlow::Configuration c | c.hasFlow(_, getAlert(file, line)) | result = " for " + c)
+ exists(DataFlow::Configuration c | c.hasFlow(_, getAlert(file, line, conf)) |
+ result = " for " + c
+ )
}
/**
- * Holds if there is a consistency-issue at `location` with description `msg`.
+ * Holds if there is a consistency-issue at `location` with description `msg` for configuration `conf`.
* The consistency issue an unexpected false positive/negative.
* Or that false positive/negative was expected, and none were found.
*/
-query predicate consistencyIssue(string location, string msg, string commentText) {
+query predicate consistencyIssue(string location, string msg, string commentText, Conf conf) {
exists(File file, int line |
- file = getATestFile() and location = file.getRelativePath() + ":" + line
+ file = getATestFile(conf) and location = file.getRelativePath() + ":" + line
|
exists(AssertionComment comment |
comment.getText().trim() = commentText and comment = getComment(file, line)
|
- falsePositive(file, line, comment) and
+ falsePositive(file, line, comment, conf) and
not comment.expectConsistencyError() and
- msg = "did not expected an alert, but found an alert" + getSinkDescription(file, line)
+ msg = "did not expect an alert, but found an alert" + getSinkDescription(file, line, conf)
or
- falseNegative(file, line, comment) and
+ falseNegative(file, line, comment, conf) and
not comment.expectConsistencyError() and
msg = "expected an alert, but found none"
or
- not falsePositive(file, line, comment) and
- not falseNegative(file, line, comment) and
+ not falsePositive(file, line, comment, conf) and
+ not falseNegative(file, line, comment, conf) and
comment.expectConsistencyError() and
msg = "expected consistency issue, but found no such issue (" + comment.getText().trim() + ")"
)