diff --git a/javascript/ql/test/library-tests/Promises/tests.expected b/javascript/ql/test/library-tests/Promises/tests.expected index 52c00a11d50c..a4d31881f243 100644 --- a/javascript/ql/test/library-tests/Promises/tests.expected +++ b/javascript/ql/test/library-tests/Promises/tests.expected @@ -275,6 +275,10 @@ flow | flow.js:136:15:136:22 | "source" | flow.js:155:9:155:9 | e | exclusiveTaintFlow | flow2.js:2:15:2:22 | "source" | flow2.js:5:8:5:10 | arr | +| flow2.js:2:15:2:22 | "source" | flow2.js:7:8:7:13 | arr[1] | +| flow2.js:2:15:2:22 | "source" | flow2.js:11:7:11:11 | clean | +| flow2.js:2:15:2:22 | "source" | flow2.js:15:7:15:12 | clean2 | +| flow2.js:2:15:2:22 | "source" | flow2.js:19:7:19:12 | clean3 | | flow.js:136:15:136:22 | "source" | flow.js:141:7:141:13 | async() | | flow.js:160:15:160:22 | "source" | flow.js:164:39:164:39 | x | | flow.js:160:15:160:22 | "source" | flow.js:167:7:167:9 | foo | @@ -468,3 +472,7 @@ valueFlowDifference | flow2.js:2:15:2:22 | "source" | flow2.js:20:7:20:14 | tainted3 | only flow with NEW data flow library | taintFlowDifference | flow2.js:2:15:2:22 | "source" | flow2.js:5:8:5:10 | arr | only flow with NEW data flow library | +| flow2.js:2:15:2:22 | "source" | flow2.js:7:8:7:13 | arr[1] | only flow with NEW data flow library | +| flow2.js:2:15:2:22 | "source" | flow2.js:11:7:11:11 | clean | only flow with NEW data flow library | +| flow2.js:2:15:2:22 | "source" | flow2.js:15:7:15:12 | clean2 | only flow with NEW data flow library | +| flow2.js:2:15:2:22 | "source" | flow2.js:19:7:19:12 | clean3 | only flow with NEW data flow library | diff --git a/javascript/ql/test/library-tests/TaintTracking/BasicTaintTracking.expected b/javascript/ql/test/library-tests/TaintTracking/BasicTaintTracking.expected index d8ba7545b0d2..94bb172aaac3 100644 --- a/javascript/ql/test/library-tests/TaintTracking/BasicTaintTracking.expected +++ b/javascript/ql/test/library-tests/TaintTracking/BasicTaintTracking.expected @@ -1,15 +1,9 @@ legacyDataFlowDifference -| arrays-init.js:2:16:2:23 | source() | arrays-init.js:27:8:27:13 | arr[0] | only flow with OLD data flow library | -| arrays-init.js:2:16:2:23 | source() | arrays-init.js:33:8:33:13 | arr[0] | only flow with OLD data flow library | -| arrays-init.js:2:16:2:23 | source() | arrays-init.js:35:8:35:13 | arr[2] | only flow with OLD data flow library | -| arrays-init.js:2:16:2:23 | source() | arrays-init.js:36:8:36:13 | arr[3] | only flow with OLD data flow library | -| arrays-init.js:2:16:2:23 | source() | arrays-init.js:37:8:37:13 | arr[4] | only flow with OLD data flow library | | bound-function.js:27:8:27:15 | source() | bound-function.js:30:10:30:10 | y | only flow with OLD data flow library | | call-apply.js:27:14:27:21 | source() | call-apply.js:24:8:24:11 | arg1 | only flow with NEW data flow library | | call-apply.js:27:14:27:21 | source() | call-apply.js:32:6:32:35 | foo1.ap ... e, ""]) | only flow with NEW data flow library | +| call-apply.js:27:14:27:21 | source() | call-apply.js:33:6:33:35 | foo2.ap ... e, ""]) | only flow with NEW data flow library | | call-apply.js:27:14:27:21 | source() | call-apply.js:34:6:34:29 | foo1_ap ... e, ""]) | only flow with NEW data flow library | -| call-apply.js:27:14:27:21 | source() | call-apply.js:41:6:41:28 | foo1_ca ... ource]) | only flow with OLD data flow library | -| call-apply.js:27:14:27:21 | source() | call-apply.js:59:10:59:21 | arguments[1] | only flow with OLD data flow library | | call-apply.js:45:8:45:15 | source() | call-apply.js:55:6:55:13 | foo(obj) | only flow with NEW data flow library | | callbacks.js:37:17:37:24 | source() | callbacks.js:38:35:38:35 | x | only flow with NEW data flow library | | callbacks.js:37:17:37:24 | source() | callbacks.js:41:10:41:10 | x | only flow with NEW data flow library | @@ -32,14 +26,28 @@ legacyDataFlowDifference | object-bypass-sanitizer.js:35:29:35:36 | source() | object-bypass-sanitizer.js:28:10:28:30 | sanitiz ... bj).foo | only flow with OLD data flow library | | promise.js:12:20:12:27 | source() | promise.js:13:8:13:23 | resolver.promise | only flow with OLD data flow library | | sanitizer-guards.js:57:11:57:18 | source() | sanitizer-guards.js:64:8:64:8 | x | only flow with NEW data flow library | +| spread.js:4:15:4:22 | source() | spread.js:17:8:17:8 | x | only flow with NEW data flow library | | spread.js:4:15:4:22 | source() | spread.js:18:8:18:8 | y | only flow with NEW data flow library | +| spread.js:4:15:4:22 | source() | spread.js:19:8:19:8 | z | only flow with NEW data flow library | +| spread.js:4:15:4:22 | source() | spread.js:23:8:23:8 | x | only flow with NEW data flow library | | spread.js:4:15:4:22 | source() | spread.js:24:8:24:8 | y | only flow with NEW data flow library | +| spread.js:4:15:4:22 | source() | spread.js:25:8:25:8 | z | only flow with NEW data flow library | | tst.js:2:13:2:20 | source() | tst.js:17:10:17:10 | a | only flow with OLD data flow library | | use-use-after-implicit-read.js:7:17:7:24 | source() | use-use-after-implicit-read.js:15:10:15:10 | x | only flow with NEW data flow library | +| use-use-after-implicit-read.js:7:17:7:24 | source() | use-use-after-implicit-read.js:16:10:16:10 | y | only flow with NEW data flow library | consistencyIssue +| arrays-init.js:27 | did not expect an alert, but found an alert for LegacyConfig | OK | Consistency | +| arrays-init.js:33 | did not expect an alert, but found an alert for LegacyConfig | OK | Consistency | +| arrays-init.js:35 | did not expect an alert, but found an alert for LegacyConfig | OK | Consistency | +| arrays-init.js:36 | did not expect an alert, but found an alert for LegacyConfig | OK | Consistency | +| arrays-init.js:37 | did not expect an alert, but found an alert for LegacyConfig | OK | Consistency | +| call-apply.js:33 | did not expect an alert, but found an alert | OK | Consistency | +| call-apply.js:41 | did not expect an alert, but found an alert for LegacyConfig | OK | Consistency | +| call-apply.js:59 | did not expect an alert, but found an alert for LegacyConfig | OK | Consistency | | nested-props.js:20 | expected an alert, but found none | NOT OK - but not found | Consistency | | stringification-read-steps.js:17 | expected an alert, but found none | NOT OK | Consistency | | stringification-read-steps.js:25 | expected an alert, but found none | NOT OK | Consistency | +| use-use-after-implicit-read.js:16 | did not expect an alert, but found an alert | OK | Consistency | flow | access-path-sanitizer.js:2:18:2:25 | source() | access-path-sanitizer.js:4:8:4:12 | obj.x | | addexpr.js:4:10:4:17 | source() | addexpr.js:7:8:7:8 | x | @@ -59,8 +67,13 @@ flow | array-mutation.js:75:28:75:35 | source() | array-mutation.js:76:8:76:8 | r | | arrays-init.js:2:16:2:23 | source() | arrays-init.js:17:8:17:13 | arr[1] | | arrays-init.js:2:16:2:23 | source() | arrays-init.js:22:8:22:13 | arr[6] | +| arrays-init.js:2:16:2:23 | source() | arrays-init.js:27:8:27:13 | arr[0] | | arrays-init.js:2:16:2:23 | source() | arrays-init.js:28:8:28:13 | arr[1] | +| arrays-init.js:2:16:2:23 | source() | arrays-init.js:33:8:33:13 | arr[0] | | arrays-init.js:2:16:2:23 | source() | arrays-init.js:34:8:34:13 | arr[1] | +| arrays-init.js:2:16:2:23 | source() | arrays-init.js:35:8:35:13 | arr[2] | +| arrays-init.js:2:16:2:23 | source() | arrays-init.js:36:8:36:13 | arr[3] | +| arrays-init.js:2:16:2:23 | source() | arrays-init.js:37:8:37:13 | arr[4] | | arrays-init.js:2:16:2:23 | source() | arrays-init.js:38:8:38:13 | arr[5] | | arrays-init.js:2:16:2:23 | source() | arrays-init.js:43:10:43:15 | arr[i] | | arrays-init.js:2:16:2:23 | source() | arrays-init.js:55:10:55:15 | arr[i] | @@ -83,8 +96,11 @@ flow | call-apply.js:27:14:27:21 | source() | call-apply.js:24:8:24:11 | arg1 | | call-apply.js:27:14:27:21 | source() | call-apply.js:29:6:29:32 | foo1.ca ... ce, "") | | call-apply.js:27:14:27:21 | source() | call-apply.js:32:6:32:35 | foo1.ap ... e, ""]) | +| call-apply.js:27:14:27:21 | source() | call-apply.js:33:6:33:35 | foo2.ap ... e, ""]) | | call-apply.js:27:14:27:21 | source() | call-apply.js:34:6:34:29 | foo1_ap ... e, ""]) | | call-apply.js:27:14:27:21 | source() | call-apply.js:40:6:40:28 | foo1_ca ... e, ""]) | +| call-apply.js:27:14:27:21 | source() | call-apply.js:41:6:41:28 | foo1_ca ... ource]) | +| call-apply.js:27:14:27:21 | source() | call-apply.js:59:10:59:21 | arguments[1] | | call-apply.js:27:14:27:21 | source() | call-apply.js:62:10:62:21 | arguments[0] | | call-apply.js:45:8:45:15 | source() | call-apply.js:55:6:55:13 | foo(obj) | | call-apply.js:81:17:81:24 | source() | call-apply.js:78:8:78:11 | this | @@ -263,8 +279,12 @@ flow | spread.js:4:15:4:22 | source() | spread.js:7:8:7:43 | { f: 'h ... orld' } | | spread.js:4:15:4:22 | source() | spread.js:9:8:9:19 | [ ...taint ] | | spread.js:4:15:4:22 | source() | spread.js:10:8:10:28 | [ 1, 2, ... nt, 3 ] | +| spread.js:4:15:4:22 | source() | spread.js:17:8:17:8 | x | | spread.js:4:15:4:22 | source() | spread.js:18:8:18:8 | y | +| spread.js:4:15:4:22 | source() | spread.js:19:8:19:8 | z | +| spread.js:4:15:4:22 | source() | spread.js:23:8:23:8 | x | | spread.js:4:15:4:22 | source() | spread.js:24:8:24:8 | y | +| spread.js:4:15:4:22 | source() | spread.js:25:8:25:8 | z | | static-capture-groups.js:2:17:2:24 | source() | static-capture-groups.js:5:14:5:22 | RegExp.$1 | | static-capture-groups.js:2:17:2:24 | source() | static-capture-groups.js:15:14:15:22 | RegExp.$1 | | static-capture-groups.js:2:17:2:24 | source() | static-capture-groups.js:17:14:17:22 | RegExp.$1 | @@ -326,6 +346,7 @@ flow | tst.js:93:22:93:29 | source() | tst.js:97:14:97:26 | map.get(true) | | use-use-after-implicit-read.js:7:17:7:24 | source() | use-use-after-implicit-read.js:8:10:8:17 | captured | | use-use-after-implicit-read.js:7:17:7:24 | source() | use-use-after-implicit-read.js:15:10:15:10 | x | +| use-use-after-implicit-read.js:7:17:7:24 | source() | use-use-after-implicit-read.js:16:10:16:10 | y | | xml.js:5:18:5:25 | source() | xml.js:8:14:8:17 | text | | xml.js:12:17:12:24 | source() | xml.js:13:14:13:19 | result | | xml.js:23:18:23:25 | source() | xml.js:20:14:20:17 | attr | diff --git a/javascript/ql/test/library-tests/TaintedUrlSuffix/tst.js b/javascript/ql/test/library-tests/TaintedUrlSuffix/tst.js index 0c755ac65128..f7ceeadb5988 100644 --- a/javascript/ql/test/library-tests/TaintedUrlSuffix/tst.js +++ b/javascript/ql/test/library-tests/TaintedUrlSuffix/tst.js @@ -8,12 +8,12 @@ function t1() { sink(href.split('#')[0]); // could be 'tainted-url-suffix', but omitted due to FPs from URI-encoding sink(href.split('#')[1]); // $ flow=taint sink(href.split('#').pop()); // $ flow=taint - sink(href.split('#')[2]); // $ MISSING: flow=taint // currently the split() summary only propagates to index 1 + sink(href.split('#')[2]); // $ flow=taint // currently the split() summary only propagates to index 1 sink(href.split('?')[0]); sink(href.split('?')[1]); // $ flow=taint sink(href.split('?').pop()); // $ flow=taint - sink(href.split('?')[2]); // $ MISSING: flow=taint + sink(href.split('?')[2]); // $ flow=taint sink(href.split(blah())[0]); // $ flow=tainted-url-suffix sink(href.split(blah())[1]); // $ flow=tainted-url-suffix diff --git a/javascript/ql/test/library-tests/TripleDot/arrays.js b/javascript/ql/test/library-tests/TripleDot/arrays.js index 0a18066eb767..ae6576bfa3ab 100644 --- a/javascript/ql/test/library-tests/TripleDot/arrays.js +++ b/javascript/ql/test/library-tests/TripleDot/arrays.js @@ -2,8 +2,8 @@ import 'dummy'; function shiftKnown() { let array = [source('shift.1'), source('shift.2')]; - sink(array.shift()); // $ hasValueFlow=shift.1 - sink(array.shift()); // $ SPURIOUS: hasValueFlow=shift.1 MISSING: hasValueFlow=shift.2 + sink(array.shift()); // $ hasValueFlow=shift.1 SPURIOUS: hasTaintFlow=shift.2 + sink(array.shift()); // $ SPURIOUS: hasValueFlow=shift.1 hasTaintFlow=shift.2 MISSING: hasValueFlow=shift.2 } function shiftUnknown() { diff --git a/javascript/ql/test/library-tests/TripleDot/tst.js b/javascript/ql/test/library-tests/TripleDot/tst.js index 6f776264e84f..58947d0143e6 100644 --- a/javascript/ql/test/library-tests/TripleDot/tst.js +++ b/javascript/ql/test/library-tests/TripleDot/tst.js @@ -2,8 +2,8 @@ import 'dummy'; function t1() { function target(...rest) { - sink(rest[0]); // $ hasValueFlow=t1.1 - sink(rest[1]); // $ hasValueFlow=t1.2 + sink(rest[0]); // $ hasValueFlow=t1.1 SPURIOUS: hasTaintFlow=t1.2 + sink(rest[1]); // $ hasValueFlow=t1.2 SPURIOUS: hasTaintFlow=t1.1 sink(rest.join(',')); // $ hasTaintFlow=t1.1 hasTaintFlow=t1.2 } target(source('t1.1'), source('t1.2')); @@ -19,9 +19,9 @@ function t2() { function t3() { function finalTarget(x, y, z) { - sink(x); // $ hasValueFlow=t3.1 - sink(y); // $ hasValueFlow=t3.2 - sink(z); // $ hasValueFlow=t3.3 + sink(x); // $ hasValueFlow=t3.1 SPURIOUS: hasTaintFlow=t3.2 hasTaintFlow=t3.3 + sink(y); // $ hasValueFlow=t3.2 SPURIOUS: hasTaintFlow=t3.1 hasTaintFlow=t3.3 + sink(z); // $ hasValueFlow=t3.3 SPURIOUS: hasTaintFlow=t3.1 hasTaintFlow=t3.2 } function target(...rest) { finalTarget(...rest); @@ -31,10 +31,10 @@ function t3() { function t4() { function finalTarget(w, x, y, z) { - sink(w); // $ hasValueFlow=t4.0 - sink(x); // $ hasValueFlow=t4.1 - sink(y); // $ hasValueFlow=t4.2 - sink(z); // $ hasValueFlow=t4.3 + sink(w); // $ hasValueFlow=t4.0 SPURIOUS: hasTaintFlow=t4.1 hasTaintFlow=t4.2 hasTaintFlow=t4.3 + sink(x); // $ hasValueFlow=t4.1 SPURIOUS: hasTaintFlow=t4.2 hasTaintFlow=t4.3 + sink(y); // $ hasValueFlow=t4.2 SPURIOUS: hasTaintFlow=t4.1 hasTaintFlow=t4.3 + sink(z); // $ hasValueFlow=t4.3 SPURIOUS: hasTaintFlow=t4.1 hasTaintFlow=t4.2 } function target(...rest) { finalTarget(source('t4.0'), ...rest); @@ -44,10 +44,10 @@ function t4() { function t5() { function finalTarget(w, x, y, z) { - sink(w); // $ hasValueFlow=t5.0 - sink(x); // $ hasValueFlow=t5.1 - sink(y); // $ hasValueFlow=t5.2 - sink(z); // $ hasValueFlow=t5.3 + sink(w); // $ hasValueFlow=t5.0 SPURIOUS: hasTaintFlow=t5.1 hasTaintFlow=t5.2 hasTaintFlow=t5.3 + sink(x); // $ hasValueFlow=t5.1 SPURIOUS: hasTaintFlow=t5.2 hasTaintFlow=t5.3 + sink(y); // $ hasValueFlow=t5.2 SPURIOUS: hasTaintFlow=t5.1 hasTaintFlow=t5.3 + sink(z); // $ hasValueFlow=t5.3 SPURIOUS: hasTaintFlow=t5.1 hasTaintFlow=t5.2 } function target(array) { finalTarget(source('t5.0'), ...array); @@ -58,18 +58,18 @@ function t5() { function t6() { function target(x) { sink(x); // $ hasValueFlow=t6.1 - sink(arguments[0]);// $ hasValueFlow=t6.1 - sink(arguments[1]);// $ hasValueFlow=t6.2 - sink(arguments[2]);// $ hasValueFlow=t6.3 + sink(arguments[0]);// $ hasValueFlow=t6.1 SPURIOUS: hasTaintFlow=t6.2 hasTaintFlow=t6.3 + sink(arguments[1]);// $ hasValueFlow=t6.2 SPURIOUS: hasTaintFlow=t6.1 hasTaintFlow=t6.3 + sink(arguments[2]);// $ hasValueFlow=t6.3 SPURIOUS: hasTaintFlow=t6.1 hasTaintFlow=t6.2 } target(source('t6.1'), source('t6.2'), source('t6.3')); } function t7() { function finalTarget(x, y, z) { - sink(x); // $ hasValueFlow=t7.1 - sink(y); // $ hasValueFlow=t7.2 - sink(z); // $ hasValueFlow=t7.3 + sink(x); // $ hasValueFlow=t7.1 SPURIOUS: hasTaintFlow=t7.2 hasTaintFlow=t7.3 + sink(y); // $ hasValueFlow=t7.2 SPURIOUS: hasTaintFlow=t7.1 hasTaintFlow=t7.3 + sink(z); // $ hasValueFlow=t7.3 SPURIOUS: hasTaintFlow=t7.1 hasTaintFlow=t7.2 } function target() { finalTarget(...arguments); @@ -79,9 +79,9 @@ function t7() { function t8() { function finalTarget(x, y, z) { - sink(x); // $ hasValueFlow=t8.1 SPURIOUS: hasValueFlow=t8.3 hasValueFlow=t8.4 - sink(y); // $ hasValueFlow=t8.2 SPURIOUS: hasValueFlow=t8.3 hasValueFlow=t8.4 - sink(z); // $ hasValueFlow=t8.3 SPURIOUS: hasValueFlow=t8.3 hasValueFlow=t8.4 + sink(x); // $ hasValueFlow=t8.1 SPURIOUS: hasTaintFlow=t8.2 hasValueFlow=t8.3 hasValueFlow=t8.4 + sink(y); // $ hasValueFlow=t8.2 SPURIOUS: hasTaintFlow=t8.1 hasValueFlow=t8.3 hasValueFlow=t8.4 + sink(z); // $ hasValueFlow=t8.3 SPURIOUS: hasTaintFlow=t8.1 hasTaintFlow=t8.2 hasValueFlow=t8.3 hasValueFlow=t8.4 } function target(array1, array2) { finalTarget(...array1, ...array2); @@ -91,9 +91,9 @@ function t8() { function t9() { function finalTarget(x, y, z) { - sink(x); // $ hasValueFlow=t9.1 - sink(y); // $ hasValueFlow=t9.2 - sink(z); // $ hasValueFlow=t9.3 + sink(x); // $ hasValueFlow=t9.1 SPURIOUS: hasTaintFlow=t9.2 hasTaintFlow=t9.3 + sink(y); // $ hasValueFlow=t9.2 SPURIOUS: hasTaintFlow=t9.1 hasTaintFlow=t9.3 + sink(z); // $ hasValueFlow=t9.3 SPURIOUS: hasTaintFlow=t9.1 hasTaintFlow=t9.2 } function target() { finalTarget.apply(undefined, arguments); @@ -103,9 +103,9 @@ function t9() { function t10() { function finalTarget(x, y, z) { - sink(x); // $ hasValueFlow=t10.1 - sink(y); // $ hasValueFlow=t10.2 - sink(z); // $ hasValueFlow=t10.3 + sink(x); // $ hasValueFlow=t10.1 SPURIOUS: hasTaintFlow=t10.2 hasTaintFlow=t10.3 + sink(y); // $ hasValueFlow=t10.2 SPURIOUS: hasTaintFlow=t10.1 hasTaintFlow=t10.3 + sink(z); // $ hasValueFlow=t10.3 SPURIOUS: hasTaintFlow=t10.1 hasTaintFlow=t10.2 } function target(...rest) { finalTarget.apply(undefined, rest); diff --git a/javascript/ql/test/library-tests/frameworks/AsyncPackage/AsyncTaintTracking.expected b/javascript/ql/test/library-tests/frameworks/AsyncPackage/AsyncTaintTracking.expected index 168f5ec5ace4..50e18f938a56 100644 --- a/javascript/ql/test/library-tests/frameworks/AsyncPackage/AsyncTaintTracking.expected +++ b/javascript/ql/test/library-tests/frameworks/AsyncPackage/AsyncTaintTracking.expected @@ -1,10 +1,10 @@ legacyDataFlowDifference -| each.js:11:9:11:16 | source() | each.js:13:12:13:15 | item | only flow with OLD data flow library | -| map.js:10:13:10:20 | source() | map.js:12:14:12:17 | item | only flow with OLD data flow library | -| map.js:26:13:26:20 | source() | map.js:28:27:28:32 | result | only flow with OLD data flow library | -| sortBy.js:10:22:10:29 | source() | sortBy.js:12:27:12:32 | result | only flow with OLD data flow library | #select +| each.js:11:9:11:16 | source() | each.js:13:12:13:15 | item | +| map.js:10:13:10:20 | source() | map.js:12:14:12:17 | item | | map.js:20:19:20:26 | source() | map.js:23:27:23:32 | result | +| map.js:26:13:26:20 | source() | map.js:28:27:28:32 | result | +| sortBy.js:10:22:10:29 | source() | sortBy.js:12:27:12:32 | result | | waterfall.js:8:30:8:37 | source() | waterfall.js:11:12:11:16 | taint | | waterfall.js:8:30:8:37 | source() | waterfall.js:20:10:20:14 | taint | | waterfall.js:28:18:28:25 | source() | waterfall.js:39:10:39:12 | err | diff --git a/javascript/ql/test/query-tests/Security/CWE-078/IndirectCommandInjection/IndirectCommandInjection.expected b/javascript/ql/test/query-tests/Security/CWE-078/IndirectCommandInjection/IndirectCommandInjection.expected index b8ce07f4ca8e..da1891b76dfc 100644 --- a/javascript/ql/test/query-tests/Security/CWE-078/IndirectCommandInjection/IndirectCommandInjection.expected +++ b/javascript/ql/test/query-tests/Security/CWE-078/IndirectCommandInjection/IndirectCommandInjection.expected @@ -17,6 +17,7 @@ edges | command-line-parameter-command-injection.js:11:14:11:17 | args | command-line-parameter-command-injection.js:11:14:11:20 | args[0] | provenance | | | command-line-parameter-command-injection.js:11:14:11:17 | args [ArrayElement] | command-line-parameter-command-injection.js:11:14:11:20 | args[0] | provenance | | | command-line-parameter-command-injection.js:12:26:12:29 | args | command-line-parameter-command-injection.js:12:14:12:32 | "cmd.sh " + args[0] | provenance | | +| command-line-parameter-command-injection.js:12:26:12:29 | args [ArrayElement] | command-line-parameter-command-injection.js:12:14:12:32 | "cmd.sh " + args[0] | provenance | | | command-line-parameter-command-injection.js:12:26:12:29 | args [ArrayElement] | command-line-parameter-command-injection.js:12:26:12:32 | args[0] | provenance | | | command-line-parameter-command-injection.js:12:26:12:32 | args[0] | command-line-parameter-command-injection.js:12:14:12:32 | "cmd.sh " + args[0] | provenance | | | command-line-parameter-command-injection.js:14:6:14:30 | fewerArgs | command-line-parameter-command-injection.js:15:14:15:22 | fewerArgs | provenance | | @@ -34,11 +35,13 @@ edges | command-line-parameter-command-injection.js:15:14:15:22 | fewerArgs | command-line-parameter-command-injection.js:15:14:15:25 | fewerArgs[0] | provenance | | | command-line-parameter-command-injection.js:15:14:15:22 | fewerArgs [ArrayElement] | command-line-parameter-command-injection.js:15:14:15:25 | fewerArgs[0] | provenance | | | command-line-parameter-command-injection.js:16:26:16:34 | fewerArgs | command-line-parameter-command-injection.js:16:14:16:37 | "cmd.sh ... Args[0] | provenance | | +| command-line-parameter-command-injection.js:16:26:16:34 | fewerArgs [ArrayElement] | command-line-parameter-command-injection.js:16:14:16:37 | "cmd.sh ... Args[0] | provenance | | | command-line-parameter-command-injection.js:16:26:16:34 | fewerArgs [ArrayElement] | command-line-parameter-command-injection.js:16:26:16:37 | fewerArgs[0] | provenance | | | command-line-parameter-command-injection.js:16:26:16:37 | fewerArgs[0] | command-line-parameter-command-injection.js:16:14:16:37 | "cmd.sh ... Args[0] | provenance | | | command-line-parameter-command-injection.js:18:6:18:24 | arg0 | command-line-parameter-command-injection.js:19:14:19:17 | arg0 | provenance | | | command-line-parameter-command-injection.js:18:6:18:24 | arg0 | command-line-parameter-command-injection.js:20:26:20:29 | arg0 | provenance | | | command-line-parameter-command-injection.js:18:13:18:21 | fewerArgs | command-line-parameter-command-injection.js:18:6:18:24 | arg0 | provenance | | +| command-line-parameter-command-injection.js:18:13:18:21 | fewerArgs [ArrayElement] | command-line-parameter-command-injection.js:18:6:18:24 | arg0 | provenance | | | command-line-parameter-command-injection.js:18:13:18:21 | fewerArgs [ArrayElement] | command-line-parameter-command-injection.js:18:13:18:24 | fewerArgs[0] | provenance | | | command-line-parameter-command-injection.js:18:13:18:24 | fewerArgs[0] | command-line-parameter-command-injection.js:18:6:18:24 | arg0 | provenance | | | command-line-parameter-command-injection.js:20:26:20:29 | arg0 | command-line-parameter-command-injection.js:20:14:20:29 | "cmd.sh " + arg0 | provenance | | @@ -51,6 +54,7 @@ edges | command-line-parameter-command-injection.js:24:15:24:35 | process ... lice(2) | command-line-parameter-command-injection.js:24:8:24:35 | args | provenance | | | command-line-parameter-command-injection.js:24:15:24:35 | process ... lice(2) [ArrayElement] | command-line-parameter-command-injection.js:24:8:24:35 | args [ArrayElement] | provenance | | | command-line-parameter-command-injection.js:26:32:26:35 | args | command-line-parameter-command-injection.js:26:14:26:50 | `node $ ... ption"` | provenance | | +| command-line-parameter-command-injection.js:26:32:26:35 | args [ArrayElement] | command-line-parameter-command-injection.js:26:14:26:50 | `node $ ... ption"` | provenance | | | command-line-parameter-command-injection.js:26:32:26:35 | args [ArrayElement] | command-line-parameter-command-injection.js:26:32:26:38 | args[0] | provenance | | | command-line-parameter-command-injection.js:26:32:26:38 | args[0] | command-line-parameter-command-injection.js:26:14:26:50 | `node $ ... ption"` | provenance | | | command-line-parameter-command-injection.js:27:32:27:35 | args | command-line-parameter-command-injection.js:27:32:27:45 | args.join(' ') | provenance | | @@ -94,16 +98,24 @@ edges | command-line-parameter-command-injection.js:71:20:71:40 | require ... ').argv | command-line-parameter-command-injection.js:71:6:71:16 | [...taint4] | provenance | | | command-line-parameter-command-injection.js:72:22:72:27 | taint4 | command-line-parameter-command-injection.js:72:10:72:27 | "cmd.sh " + taint4 | provenance | | | command-line-parameter-command-injection.js:76:8:76:35 | argv | command-line-parameter-command-injection.js:79:31:79:34 | argv | provenance | | +| command-line-parameter-command-injection.js:76:8:76:35 | argv [ArrayElement] | command-line-parameter-command-injection.js:79:31:79:34 | argv [ArrayElement] | provenance | | | command-line-parameter-command-injection.js:76:15:76:26 | process.argv | command-line-parameter-command-injection.js:76:15:76:35 | process ... lice(2) | provenance | | +| command-line-parameter-command-injection.js:76:15:76:26 | process.argv | command-line-parameter-command-injection.js:76:15:76:35 | process ... lice(2) [ArrayElement] | provenance | | | command-line-parameter-command-injection.js:76:15:76:35 | process ... lice(2) | command-line-parameter-command-injection.js:76:8:76:35 | argv | provenance | | +| command-line-parameter-command-injection.js:76:15:76:35 | process ... lice(2) [ArrayElement] | command-line-parameter-command-injection.js:76:8:76:35 | argv [ArrayElement] | provenance | | | command-line-parameter-command-injection.js:79:22:79:35 | minimist(argv) | command-line-parameter-command-injection.js:79:10:79:39 | "cmd.sh ... gv).foo | provenance | | | command-line-parameter-command-injection.js:79:31:79:34 | argv | command-line-parameter-command-injection.js:79:22:79:35 | minimist(argv) | provenance | | +| command-line-parameter-command-injection.js:79:31:79:34 | argv [ArrayElement] | command-line-parameter-command-injection.js:79:22:79:35 | minimist(argv) | provenance | | | command-line-parameter-command-injection.js:82:22:82:50 | subarg( ... ice(2)) | command-line-parameter-command-injection.js:82:10:82:54 | "cmd.sh ... 2)).foo | provenance | | | command-line-parameter-command-injection.js:82:29:82:40 | process.argv | command-line-parameter-command-injection.js:82:29:82:49 | process ... lice(2) | provenance | | +| command-line-parameter-command-injection.js:82:29:82:40 | process.argv | command-line-parameter-command-injection.js:82:29:82:49 | process ... lice(2) [ArrayElement] | provenance | | | command-line-parameter-command-injection.js:82:29:82:49 | process ... lice(2) | command-line-parameter-command-injection.js:82:22:82:50 | subarg( ... ice(2)) | provenance | | +| command-line-parameter-command-injection.js:82:29:82:49 | process ... lice(2) [ArrayElement] | command-line-parameter-command-injection.js:82:22:82:50 | subarg( ... ice(2)) | provenance | | | command-line-parameter-command-injection.js:85:22:85:55 | yargsPa ... ice(2)) | command-line-parameter-command-injection.js:85:10:85:59 | "cmd.sh ... 2)).foo | provenance | | | command-line-parameter-command-injection.js:85:34:85:45 | process.argv | command-line-parameter-command-injection.js:85:34:85:54 | process ... lice(2) | provenance | | +| command-line-parameter-command-injection.js:85:34:85:45 | process.argv | command-line-parameter-command-injection.js:85:34:85:54 | process ... lice(2) [ArrayElement] | provenance | | | command-line-parameter-command-injection.js:85:34:85:54 | process ... lice(2) | command-line-parameter-command-injection.js:85:22:85:55 | yargsPa ... ice(2)) | provenance | | +| command-line-parameter-command-injection.js:85:34:85:54 | process ... lice(2) [ArrayElement] | command-line-parameter-command-injection.js:85:22:85:55 | yargsPa ... ice(2)) | provenance | | | command-line-parameter-command-injection.js:88:6:88:37 | flags | command-line-parameter-command-injection.js:89:22:89:26 | flags | provenance | | | command-line-parameter-command-injection.js:88:14:88:37 | args.pa ... s.argv) | command-line-parameter-command-injection.js:88:6:88:37 | flags | provenance | | | command-line-parameter-command-injection.js:88:25:88:36 | process.argv | command-line-parameter-command-injection.js:88:14:88:37 | args.pa ... s.argv) | provenance | | @@ -237,19 +249,24 @@ nodes | command-line-parameter-command-injection.js:72:10:72:27 | "cmd.sh " + taint4 | semmle.label | "cmd.sh " + taint4 | | command-line-parameter-command-injection.js:72:22:72:27 | taint4 | semmle.label | taint4 | | command-line-parameter-command-injection.js:76:8:76:35 | argv | semmle.label | argv | +| command-line-parameter-command-injection.js:76:8:76:35 | argv [ArrayElement] | semmle.label | argv [ArrayElement] | | command-line-parameter-command-injection.js:76:15:76:26 | process.argv | semmle.label | process.argv | | command-line-parameter-command-injection.js:76:15:76:35 | process ... lice(2) | semmle.label | process ... lice(2) | +| command-line-parameter-command-injection.js:76:15:76:35 | process ... lice(2) [ArrayElement] | semmle.label | process ... lice(2) [ArrayElement] | | command-line-parameter-command-injection.js:79:10:79:39 | "cmd.sh ... gv).foo | semmle.label | "cmd.sh ... gv).foo | | command-line-parameter-command-injection.js:79:22:79:35 | minimist(argv) | semmle.label | minimist(argv) | | command-line-parameter-command-injection.js:79:31:79:34 | argv | semmle.label | argv | +| command-line-parameter-command-injection.js:79:31:79:34 | argv [ArrayElement] | semmle.label | argv [ArrayElement] | | command-line-parameter-command-injection.js:82:10:82:54 | "cmd.sh ... 2)).foo | semmle.label | "cmd.sh ... 2)).foo | | command-line-parameter-command-injection.js:82:22:82:50 | subarg( ... ice(2)) | semmle.label | subarg( ... ice(2)) | | command-line-parameter-command-injection.js:82:29:82:40 | process.argv | semmle.label | process.argv | | command-line-parameter-command-injection.js:82:29:82:49 | process ... lice(2) | semmle.label | process ... lice(2) | +| command-line-parameter-command-injection.js:82:29:82:49 | process ... lice(2) [ArrayElement] | semmle.label | process ... lice(2) [ArrayElement] | | command-line-parameter-command-injection.js:85:10:85:59 | "cmd.sh ... 2)).foo | semmle.label | "cmd.sh ... 2)).foo | | command-line-parameter-command-injection.js:85:22:85:55 | yargsPa ... ice(2)) | semmle.label | yargsPa ... ice(2)) | | command-line-parameter-command-injection.js:85:34:85:45 | process.argv | semmle.label | process.argv | | command-line-parameter-command-injection.js:85:34:85:54 | process ... lice(2) | semmle.label | process ... lice(2) | +| command-line-parameter-command-injection.js:85:34:85:54 | process ... lice(2) [ArrayElement] | semmle.label | process ... lice(2) [ArrayElement] | | command-line-parameter-command-injection.js:88:6:88:37 | flags | semmle.label | flags | | command-line-parameter-command-injection.js:88:14:88:37 | args.pa ... s.argv) | semmle.label | args.pa ... s.argv) | | command-line-parameter-command-injection.js:88:25:88:36 | process.argv | semmle.label | process.argv | diff --git a/javascript/ql/test/query-tests/Security/CWE-079/ReflectedXss/ReflectedXss.expected b/javascript/ql/test/query-tests/Security/CWE-079/ReflectedXss/ReflectedXss.expected index 682a0694ce4c..deb17edef387 100644 --- a/javascript/ql/test/query-tests/Security/CWE-079/ReflectedXss/ReflectedXss.expected +++ b/javascript/ql/test/query-tests/Security/CWE-079/ReflectedXss/ReflectedXss.expected @@ -2,6 +2,11 @@ edges | ReflectedXss.js:8:33:8:45 | req.params.id | ReflectedXss.js:8:14:8:45 | "Unknow ... rams.id | provenance | | | ReflectedXss.js:17:31:17:39 | params.id | ReflectedXss.js:17:12:17:39 | "Unknow ... rams.id | provenance | | | ReflectedXss.js:23:19:23:26 | req.body | ReflectedXss.js:23:12:23:27 | marked(req.body) | provenance | | +| ReflectedXss.js:30:7:33:4 | mytable | ReflectedXss.js:34:12:34:18 | mytable | provenance | | +| ReflectedXss.js:30:17:33:4 | table([ ... y]\\n ]) | ReflectedXss.js:30:7:33:4 | mytable | provenance | | +| ReflectedXss.js:30:23:33:3 | [\\n [ ... dy]\\n ] [1, 1] | ReflectedXss.js:30:17:33:4 | table([ ... y]\\n ]) | provenance | | +| ReflectedXss.js:32:5:32:22 | ['body', req.body] [1] | ReflectedXss.js:30:23:33:3 | [\\n [ ... dy]\\n ] [1, 1] | provenance | | +| ReflectedXss.js:32:14:32:21 | req.body | ReflectedXss.js:32:5:32:22 | ['body', req.body] [1] | provenance | | | ReflectedXss.js:42:31:42:38 | req.body | ReflectedXss.js:42:12:42:39 | convert ... q.body) | provenance | | | ReflectedXss.js:64:14:64:21 | req.body | ReflectedXss.js:64:39:64:42 | file | provenance | | | ReflectedXss.js:64:39:64:42 | file | ReflectedXss.js:65:16:65:19 | file | provenance | | @@ -30,6 +35,7 @@ edges | ReflectedXss.js:119:11:119:72 | invalidKeys | ReflectedXss.js:122:33:122:43 | invalidKeys | provenance | | | ReflectedXss.js:119:11:119:72 | invalidKeys [0] | ReflectedXss.js:122:33:122:43 | invalidKeys [0] | provenance | | | ReflectedXss.js:119:25:119:32 | keyArray | ReflectedXss.js:119:25:119:72 | keyArra ... s(key)) | provenance | | +| ReflectedXss.js:119:25:119:32 | keyArray [0] | ReflectedXss.js:119:25:119:72 | keyArra ... s(key)) | provenance | | | ReflectedXss.js:119:25:119:32 | keyArray [0] | ReflectedXss.js:119:25:119:72 | keyArra ... s(key)) [0] | provenance | | | ReflectedXss.js:119:25:119:72 | keyArra ... s(key)) | ReflectedXss.js:119:11:119:72 | invalidKeys | provenance | | | ReflectedXss.js:119:25:119:72 | keyArra ... s(key)) [0] | ReflectedXss.js:119:11:119:72 | invalidKeys [0] | provenance | | @@ -44,9 +50,13 @@ edges | ReflectedXssGood3.js:68:22:68:26 | value | ReflectedXssGood3.js:105:18:105:22 | value | provenance | | | ReflectedXssGood3.js:77:7:77:37 | parts | ReflectedXssGood3.js:108:10:108:14 | parts | provenance | | | ReflectedXssGood3.js:77:7:77:37 | parts [0] | ReflectedXssGood3.js:108:10:108:14 | parts [0] | provenance | | +| ReflectedXssGood3.js:77:15:77:37 | [value. ... (0, i)] | ReflectedXssGood3.js:77:7:77:37 | parts | provenance | | +| ReflectedXssGood3.js:77:15:77:37 | [value. ... (0, i)] | ReflectedXssGood3.js:108:10:108:23 | parts.join('') | provenance | | | ReflectedXssGood3.js:77:15:77:37 | [value. ... (0, i)] [0] | ReflectedXssGood3.js:77:7:77:37 | parts [0] | provenance | | +| ReflectedXssGood3.js:77:15:77:37 | [value. ... (0, i)] [0] | ReflectedXssGood3.js:108:10:108:23 | parts.join('') | provenance | | | ReflectedXssGood3.js:77:16:77:20 | value | ReflectedXssGood3.js:77:16:77:36 | value.s ... g(0, i) | provenance | | | ReflectedXssGood3.js:77:16:77:36 | value.s ... g(0, i) | ReflectedXssGood3.js:77:7:77:37 | parts | provenance | | +| ReflectedXssGood3.js:77:16:77:36 | value.s ... g(0, i) | ReflectedXssGood3.js:77:15:77:37 | [value. ... (0, i)] | provenance | | | ReflectedXssGood3.js:77:16:77:36 | value.s ... g(0, i) | ReflectedXssGood3.js:77:15:77:37 | [value. ... (0, i)] [0] | provenance | | | ReflectedXssGood3.js:77:16:77:36 | value.s ... g(0, i) | ReflectedXssGood3.js:108:10:108:23 | parts.join('') | provenance | | | ReflectedXssGood3.js:105:7:105:11 | [post update] parts | ReflectedXssGood3.js:108:10:108:14 | parts | provenance | | @@ -154,6 +164,12 @@ nodes | ReflectedXss.js:23:12:23:27 | marked(req.body) | semmle.label | marked(req.body) | | ReflectedXss.js:23:19:23:26 | req.body | semmle.label | req.body | | ReflectedXss.js:29:12:29:19 | req.body | semmle.label | req.body | +| ReflectedXss.js:30:7:33:4 | mytable | semmle.label | mytable | +| ReflectedXss.js:30:17:33:4 | table([ ... y]\\n ]) | semmle.label | table([ ... y]\\n ]) | +| ReflectedXss.js:30:23:33:3 | [\\n [ ... dy]\\n ] [1, 1] | semmle.label | [\\n [ ... dy]\\n ] [1, 1] | +| ReflectedXss.js:32:5:32:22 | ['body', req.body] [1] | semmle.label | ['body', req.body] [1] | +| ReflectedXss.js:32:14:32:21 | req.body | semmle.label | req.body | +| ReflectedXss.js:34:12:34:18 | mytable | semmle.label | mytable | | ReflectedXss.js:41:12:41:19 | req.body | semmle.label | req.body | | ReflectedXss.js:42:12:42:39 | convert ... q.body) | semmle.label | convert ... q.body) | | ReflectedXss.js:42:31:42:38 | req.body | semmle.label | req.body | @@ -214,6 +230,7 @@ nodes | ReflectedXssGood3.js:68:22:68:26 | value | semmle.label | value | | ReflectedXssGood3.js:77:7:77:37 | parts | semmle.label | parts | | ReflectedXssGood3.js:77:7:77:37 | parts [0] | semmle.label | parts [0] | +| ReflectedXssGood3.js:77:15:77:37 | [value. ... (0, i)] | semmle.label | [value. ... (0, i)] | | ReflectedXssGood3.js:77:15:77:37 | [value. ... (0, i)] [0] | semmle.label | [value. ... (0, i)] [0] | | ReflectedXssGood3.js:77:16:77:20 | value | semmle.label | value | | ReflectedXssGood3.js:77:16:77:36 | value.s ... g(0, i) | semmle.label | value.s ... g(0, i) | @@ -343,6 +360,7 @@ subpaths | ReflectedXss.js:22:12:22:19 | req.body | ReflectedXss.js:22:12:22:19 | req.body | ReflectedXss.js:22:12:22:19 | req.body | Cross-site scripting vulnerability due to a $@. | ReflectedXss.js:22:12:22:19 | req.body | user-provided value | | ReflectedXss.js:23:12:23:27 | marked(req.body) | ReflectedXss.js:23:19:23:26 | req.body | ReflectedXss.js:23:12:23:27 | marked(req.body) | Cross-site scripting vulnerability due to a $@. | ReflectedXss.js:23:19:23:26 | req.body | user-provided value | | ReflectedXss.js:29:12:29:19 | req.body | ReflectedXss.js:29:12:29:19 | req.body | ReflectedXss.js:29:12:29:19 | req.body | Cross-site scripting vulnerability due to a $@. | ReflectedXss.js:29:12:29:19 | req.body | user-provided value | +| ReflectedXss.js:34:12:34:18 | mytable | ReflectedXss.js:32:14:32:21 | req.body | ReflectedXss.js:34:12:34:18 | mytable | Cross-site scripting vulnerability due to a $@. | ReflectedXss.js:32:14:32:21 | req.body | user-provided value | | ReflectedXss.js:41:12:41:19 | req.body | ReflectedXss.js:41:12:41:19 | req.body | ReflectedXss.js:41:12:41:19 | req.body | Cross-site scripting vulnerability due to a $@. | ReflectedXss.js:41:12:41:19 | req.body | user-provided value | | ReflectedXss.js:42:12:42:39 | convert ... q.body) | ReflectedXss.js:42:31:42:38 | req.body | ReflectedXss.js:42:12:42:39 | convert ... q.body) | Cross-site scripting vulnerability due to a $@. | ReflectedXss.js:42:31:42:38 | req.body | user-provided value | | ReflectedXss.js:56:12:56:19 | req.body | ReflectedXss.js:56:12:56:19 | req.body | ReflectedXss.js:56:12:56:19 | req.body | Cross-site scripting vulnerability due to a $@. | ReflectedXss.js:56:12:56:19 | req.body | user-provided value | diff --git a/javascript/ql/test/query-tests/Security/CWE-079/ReflectedXss/ReflectedXss.js b/javascript/ql/test/query-tests/Security/CWE-079/ReflectedXss/ReflectedXss.js index c3b1cbc2da8a..bffcdbc62233 100644 --- a/javascript/ql/test/query-tests/Security/CWE-079/ReflectedXss/ReflectedXss.js +++ b/javascript/ql/test/query-tests/Security/CWE-079/ReflectedXss/ReflectedXss.js @@ -31,7 +31,7 @@ app.get('/user/:id', function(req, res) { ['Name', 'Content'], ['body', req.body] ]); - res.send(mytable); // NOT OK - FIXME: only works in OLD dataflow, add implicit reads before library-contributed taint steps + res.send(mytable); // NOT OK }); var showdown = require('showdown'); @@ -99,7 +99,7 @@ app.get('/user/:id', function (req, res) { res.send(markdownIt2.render(req.body)); // OK - no html res.send(markdownIt3.render(req.body)); // NOT OK - res.send(markdownIt.use(require('markdown-it-sanitizer')).render(req.body)); // OK - HTML is sanitized. + res.send(markdownIt.use(require('markdown-it-sanitizer')).render(req.body)); // OK - HTML is sanitized. res.send(markdownIt.use(require('markdown-it-abbr')).use(unknown).render(req.body)); // NOT OK }); @@ -122,4 +122,4 @@ app.get("invalid/keys/:id", async (req, res) => { res.status(400).send(`${invalidKeys.join(', ')} not in whitelist`); return; } -}); \ No newline at end of file +}); diff --git a/javascript/ql/test/query-tests/Security/CWE-079/ReflectedXss/ReflectedXssWithCustomSanitizer.expected b/javascript/ql/test/query-tests/Security/CWE-079/ReflectedXss/ReflectedXssWithCustomSanitizer.expected index d29b35203b80..a367f07307a5 100644 --- a/javascript/ql/test/query-tests/Security/CWE-079/ReflectedXss/ReflectedXssWithCustomSanitizer.expected +++ b/javascript/ql/test/query-tests/Security/CWE-079/ReflectedXss/ReflectedXssWithCustomSanitizer.expected @@ -3,6 +3,7 @@ | ReflectedXss.js:22:12:22:19 | req.body | Cross-site scripting vulnerability due to $@. | ReflectedXss.js:22:12:22:19 | req.body | user-provided value | | ReflectedXss.js:23:12:23:27 | marked(req.body) | Cross-site scripting vulnerability due to $@. | ReflectedXss.js:23:19:23:26 | req.body | user-provided value | | ReflectedXss.js:29:12:29:19 | req.body | Cross-site scripting vulnerability due to $@. | ReflectedXss.js:29:12:29:19 | req.body | user-provided value | +| ReflectedXss.js:34:12:34:18 | mytable | Cross-site scripting vulnerability due to $@. | ReflectedXss.js:32:14:32:21 | req.body | user-provided value | | ReflectedXss.js:41:12:41:19 | req.body | Cross-site scripting vulnerability due to $@. | ReflectedXss.js:41:12:41:19 | req.body | user-provided value | | ReflectedXss.js:42:12:42:39 | convert ... q.body) | Cross-site scripting vulnerability due to $@. | ReflectedXss.js:42:31:42:38 | req.body | user-provided value | | ReflectedXss.js:56:12:56:19 | req.body | Cross-site scripting vulnerability due to $@. | ReflectedXss.js:56:12:56:19 | req.body | user-provided value | diff --git a/javascript/ql/test/query-tests/Security/CWE-400/ReDoS/PolynomialReDoS.expected b/javascript/ql/test/query-tests/Security/CWE-400/ReDoS/PolynomialReDoS.expected index 83d8243c269f..6ba6d1dd095b 100644 --- a/javascript/ql/test/query-tests/Security/CWE-400/ReDoS/PolynomialReDoS.expected +++ b/javascript/ql/test/query-tests/Security/CWE-400/ReDoS/PolynomialReDoS.expected @@ -5,6 +5,7 @@ edges | lib/lib.js:7:19:7:22 | name | lib/lib.js:8:13:8:16 | name | provenance | | | lib/lib.js:32:32:32:40 | [apply call taint node] | lib/lib.js:32:32:32:40 | arguments [ArrayElement] | provenance | | | lib/lib.js:32:32:32:40 | arguments | lib/lib.js:32:32:32:40 | [apply call taint node] | provenance | | +| lib/lib.js:32:32:32:40 | arguments [ArrayElement] | lib/lib.js:32:32:32:40 | [apply call taint node] | provenance | | | lib/lib.js:32:32:32:40 | arguments [ArrayElement] | lib/lib.js:35:28:35:31 | name | provenance | | | lib/lib.js:35:28:35:31 | name | lib/lib.js:36:13:36:16 | name | provenance | | | lib/lib.js:41:32:41:35 | name | lib/lib.js:42:17:42:20 | name | provenance | | diff --git a/javascript/ql/test/query-tests/Security/CWE-601/ClientSideUrlRedirect/ClientSideUrlRedirect.expected b/javascript/ql/test/query-tests/Security/CWE-601/ClientSideUrlRedirect/ClientSideUrlRedirect.expected index 98a139c2fb11..08a8deb06852 100644 --- a/javascript/ql/test/query-tests/Security/CWE-601/ClientSideUrlRedirect/ClientSideUrlRedirect.expected +++ b/javascript/ql/test/query-tests/Security/CWE-601/ClientSideUrlRedirect/ClientSideUrlRedirect.expected @@ -50,6 +50,10 @@ nodes | tst2.js:2:14:2:33 | window.location.href | semmle.label | window.location.href | | tst2.js:4:21:4:24 | href | semmle.label | href | | tst2.js:4:21:4:55 | href.su ... '?')+1) | semmle.label | href.su ... '?')+1) | +| tst5.js:2:19:2:33 | window.location | semmle.label | window.location | +| tst5.js:2:19:2:44 | window. ... tring() | semmle.label | window. ... tring() | +| tst5.js:2:19:2:55 | window. ... it('?') [1] | semmle.label | window. ... it('?') [1] | +| tst5.js:2:19:2:78 | window. ... s.value | semmle.label | window. ... s.value | | tst6.js:2:7:2:45 | redirect | semmle.label | redirect | | tst6.js:2:18:2:45 | $locati ... irect') | semmle.label | $locati ... irect') | | tst6.js:4:21:4:28 | redirect | semmle.label | redirect | @@ -74,6 +78,12 @@ nodes | tst10.js:14:17:14:69 | 'https: ... ring(1) | semmle.label | 'https: ... ring(1) | | tst10.js:14:33:14:56 | documen ... .search | semmle.label | documen ... .search | | tst10.js:14:33:14:69 | documen ... ring(1) | semmle.label | documen ... ring(1) | +| tst12.js:2:9:2:50 | urlParts [1] | semmle.label | urlParts [1] | +| tst12.js:2:20:2:39 | window.location.hash | semmle.label | window.location.hash | +| tst12.js:2:20:2:50 | window. ... it('?') [1] | semmle.label | window. ... it('?') [1] | +| tst12.js:3:9:3:45 | loc | semmle.label | loc | +| tst12.js:3:15:3:22 | urlParts [1] | semmle.label | urlParts [1] | +| tst12.js:4:23:4:25 | loc | semmle.label | loc | | tst13.js:2:9:2:52 | payload | semmle.label | payload | | tst13.js:2:19:2:42 | documen ... .search | semmle.label | documen ... .search | | tst13.js:2:19:2:52 | documen ... bstr(1) | semmle.label | documen ... bstr(1) | @@ -233,6 +243,9 @@ edges | tst2.js:2:7:2:33 | href | tst2.js:4:21:4:24 | href | provenance | | | tst2.js:2:14:2:33 | window.location.href | tst2.js:2:7:2:33 | href | provenance | | | tst2.js:4:21:4:24 | href | tst2.js:4:21:4:55 | href.su ... '?')+1) | provenance | Config | +| tst5.js:2:19:2:33 | window.location | tst5.js:2:19:2:44 | window. ... tring() | provenance | | +| tst5.js:2:19:2:44 | window. ... tring() | tst5.js:2:19:2:55 | window. ... it('?') [1] | provenance | Config | +| tst5.js:2:19:2:55 | window. ... it('?') [1] | tst5.js:2:19:2:78 | window. ... s.value | provenance | | | tst6.js:2:7:2:45 | redirect | tst6.js:4:21:4:28 | redirect | provenance | | | tst6.js:2:7:2:45 | redirect | tst6.js:6:17:6:24 | redirect | provenance | | | tst6.js:2:18:2:45 | $locati ... irect') | tst6.js:2:7:2:45 | redirect | provenance | | @@ -248,6 +261,11 @@ edges | tst10.js:11:27:11:63 | documen ... ring(1) | tst10.js:11:17:11:63 | '//foo' ... ring(1) | provenance | | | tst10.js:14:33:14:56 | documen ... .search | tst10.js:14:33:14:69 | documen ... ring(1) | provenance | Config | | tst10.js:14:33:14:69 | documen ... ring(1) | tst10.js:14:17:14:69 | 'https: ... ring(1) | provenance | | +| tst12.js:2:9:2:50 | urlParts [1] | tst12.js:3:15:3:22 | urlParts [1] | provenance | | +| tst12.js:2:20:2:39 | window.location.hash | tst12.js:2:20:2:50 | window. ... it('?') [1] | provenance | Config | +| tst12.js:2:20:2:50 | window. ... it('?') [1] | tst12.js:2:9:2:50 | urlParts [1] | provenance | | +| tst12.js:3:9:3:45 | loc | tst12.js:4:23:4:25 | loc | provenance | | +| tst12.js:3:15:3:22 | urlParts [1] | tst12.js:3:9:3:45 | loc | provenance | | | tst13.js:2:9:2:52 | payload | tst13.js:4:15:4:21 | payload | provenance | | | tst13.js:2:9:2:52 | payload | tst13.js:8:21:8:27 | payload | provenance | | | tst13.js:2:9:2:52 | payload | tst13.js:12:14:12:20 | payload | provenance | | @@ -366,6 +384,7 @@ subpaths | sanitizer.js:31:27:31:29 | url | sanitizer.js:2:15:2:25 | window.name | sanitizer.js:31:27:31:29 | url | Untrusted URL redirection depends on a $@. | sanitizer.js:2:15:2:25 | window.name | user-provided value | | sanitizer.js:37:27:37:29 | url | sanitizer.js:2:15:2:25 | window.name | sanitizer.js:37:27:37:29 | url | Untrusted URL redirection depends on a $@. | sanitizer.js:2:15:2:25 | window.name | user-provided value | | tst2.js:4:21:4:55 | href.su ... '?')+1) | tst2.js:2:14:2:33 | window.location.href | tst2.js:4:21:4:55 | href.su ... '?')+1) | Untrusted URL redirection depends on a $@. | tst2.js:2:14:2:33 | window.location.href | user-provided value | +| tst5.js:2:19:2:78 | window. ... s.value | tst5.js:2:19:2:33 | window.location | tst5.js:2:19:2:78 | window. ... s.value | Untrusted URL redirection depends on a $@. | tst5.js:2:19:2:33 | window.location | user-provided value | | tst6.js:4:21:4:28 | redirect | tst6.js:2:18:2:45 | $locati ... irect') | tst6.js:4:21:4:28 | redirect | Untrusted URL redirection depends on a $@. | tst6.js:2:18:2:45 | $locati ... irect') | user-provided value | | tst6.js:6:17:6:24 | redirect | tst6.js:2:18:2:45 | $locati ... irect') | tst6.js:6:17:6:24 | redirect | Untrusted URL redirection depends on a $@. | tst6.js:2:18:2:45 | $locati ... irect') | user-provided value | | tst6.js:8:21:8:56 | $locati ... + "foo" | tst6.js:8:21:8:48 | $locati ... irect') | tst6.js:8:21:8:56 | $locati ... + "foo" | Untrusted URL redirection depends on a $@. | tst6.js:8:21:8:48 | $locati ... irect') | user-provided value | @@ -376,6 +395,7 @@ subpaths | tst10.js:8:17:8:60 | '//' + ... ring(1) | tst10.js:8:24:8:47 | documen ... .search | tst10.js:8:17:8:60 | '//' + ... ring(1) | Untrusted URL redirection depends on a $@. | tst10.js:8:24:8:47 | documen ... .search | user-provided value | | tst10.js:11:17:11:63 | '//foo' ... ring(1) | tst10.js:11:27:11:50 | documen ... .search | tst10.js:11:17:11:63 | '//foo' ... ring(1) | Untrusted URL redirection depends on a $@. | tst10.js:11:27:11:50 | documen ... .search | user-provided value | | tst10.js:14:17:14:69 | 'https: ... ring(1) | tst10.js:14:33:14:56 | documen ... .search | tst10.js:14:17:14:69 | 'https: ... ring(1) | Untrusted URL redirection depends on a $@. | tst10.js:14:33:14:56 | documen ... .search | user-provided value | +| tst12.js:4:23:4:25 | loc | tst12.js:2:20:2:39 | window.location.hash | tst12.js:4:23:4:25 | loc | Untrusted URL redirection depends on a $@. | tst12.js:2:20:2:39 | window.location.hash | user-provided value | | tst13.js:4:15:4:21 | payload | tst13.js:2:19:2:42 | documen ... .search | tst13.js:4:15:4:21 | payload | Untrusted URL redirection depends on a $@. | tst13.js:2:19:2:42 | documen ... .search | user-provided value | | tst13.js:8:21:8:27 | payload | tst13.js:2:19:2:42 | documen ... .search | tst13.js:8:21:8:27 | payload | Untrusted URL redirection depends on a $@. | tst13.js:2:19:2:42 | documen ... .search | user-provided value | | tst13.js:12:14:12:20 | payload | tst13.js:2:19:2:42 | documen ... .search | tst13.js:12:14:12:20 | payload | Untrusted URL redirection depends on a $@. | tst13.js:2:19:2:42 | documen ... .search | user-provided value | diff --git a/javascript/ql/test/query-tests/Security/CWE-601/ClientSideUrlRedirect/tst12.js b/javascript/ql/test/query-tests/Security/CWE-601/ClientSideUrlRedirect/tst12.js index e5427b7d5ee1..a72efac94d36 100644 --- a/javascript/ql/test/query-tests/Security/CWE-601/ClientSideUrlRedirect/tst12.js +++ b/javascript/ql/test/query-tests/Security/CWE-601/ClientSideUrlRedirect/tst12.js @@ -1,5 +1,5 @@ function foo() { var urlParts = window.location.hash.split('?'); var loc = urlParts[0] + "?" + boxes.value; - window.location = loc; // OK - always starts with '#' + window.location = loc; // OK [INCONSISTENCY] - always starts with '#' } diff --git a/javascript/ql/test/query-tests/Security/CWE-601/ClientSideUrlRedirect/tst5.js b/javascript/ql/test/query-tests/Security/CWE-601/ClientSideUrlRedirect/tst5.js index ea73b4be04dd..e39334107175 100644 --- a/javascript/ql/test/query-tests/Security/CWE-601/ClientSideUrlRedirect/tst5.js +++ b/javascript/ql/test/query-tests/Security/CWE-601/ClientSideUrlRedirect/tst5.js @@ -1,2 +1,2 @@ -// OK +// OK [INCONSISTENCY] window.location = window.location.toString().split('?')[0] + '?' + boxes.value; diff --git a/javascript/ql/test/query-tests/Security/CWE-730/RegExpInjection.expected b/javascript/ql/test/query-tests/Security/CWE-730/RegExpInjection.expected index 86ac47a8e16f..870836b8573d 100644 --- a/javascript/ql/test/query-tests/Security/CWE-730/RegExpInjection.expected +++ b/javascript/ql/test/query-tests/Security/CWE-730/RegExpInjection.expected @@ -31,6 +31,7 @@ edges | RegExpInjection.js:54:14:54:16 | key | RegExpInjection.js:54:14:54:27 | key.split(".") | provenance | | | RegExpInjection.js:54:14:54:16 | key | RegExpInjection.js:54:14:54:27 | key.split(".") [ArrayElement] | provenance | | | RegExpInjection.js:54:14:54:27 | key.split(".") | RegExpInjection.js:54:14:54:42 | key.spl ... x => x) | provenance | | +| RegExpInjection.js:54:14:54:27 | key.split(".") [ArrayElement] | RegExpInjection.js:54:14:54:42 | key.spl ... x => x) | provenance | | | RegExpInjection.js:54:14:54:27 | key.split(".") [ArrayElement] | RegExpInjection.js:54:14:54:42 | key.spl ... x => x) [ArrayElement] | provenance | | | RegExpInjection.js:54:14:54:42 | key.spl ... x => x) | RegExpInjection.js:54:14:54:52 | key.spl ... in("-") | provenance | | | RegExpInjection.js:54:14:54:42 | key.spl ... x => x) [ArrayElement] | RegExpInjection.js:54:14:54:52 | key.spl ... in("-") | provenance | | diff --git a/rust/ql/test/library-tests/dataflow/strings/inline-taint-flow.expected b/rust/ql/test/library-tests/dataflow/strings/inline-taint-flow.expected index 0e6b9351ac7e..192b14cd8efe 100644 --- a/rust/ql/test/library-tests/dataflow/strings/inline-taint-flow.expected +++ b/rust/ql/test/library-tests/dataflow/strings/inline-taint-flow.expected @@ -11,6 +11,10 @@ edges | main.rs:32:9:32:10 | s1 | main.rs:35:9:35:10 | s4 | provenance | | | main.rs:32:14:32:23 | source(...) | main.rs:32:9:32:10 | s1 | provenance | | | main.rs:35:9:35:10 | s4 | main.rs:38:10:38:11 | s4 | provenance | | +| main.rs:43:9:43:10 | s1 | main.rs:46:34:46:35 | s1 | provenance | | +| main.rs:43:14:43:23 | source(...) | main.rs:43:9:43:10 | s1 | provenance | | +| main.rs:46:33:46:35 | &s1 [&ref] | main.rs:46:10:46:35 | ... + ... | provenance | | +| main.rs:46:34:46:35 | s1 | main.rs:46:33:46:35 | &s1 [&ref] | provenance | | | main.rs:63:9:63:9 | s | main.rs:64:16:64:16 | s | provenance | | | main.rs:63:13:63:22 | source(...) | main.rs:63:9:63:9 | s | provenance | | | main.rs:64:16:64:16 | s | main.rs:64:16:64:25 | s.as_str(...) | provenance | MaD:1 | @@ -52,6 +56,11 @@ nodes | main.rs:32:14:32:23 | source(...) | semmle.label | source(...) | | main.rs:35:9:35:10 | s4 | semmle.label | s4 | | main.rs:38:10:38:11 | s4 | semmle.label | s4 | +| main.rs:43:9:43:10 | s1 | semmle.label | s1 | +| main.rs:43:14:43:23 | source(...) | semmle.label | source(...) | +| main.rs:46:10:46:35 | ... + ... | semmle.label | ... + ... | +| main.rs:46:33:46:35 | &s1 [&ref] | semmle.label | &s1 [&ref] | +| main.rs:46:34:46:35 | s1 | semmle.label | s1 | | main.rs:63:9:63:9 | s | semmle.label | s | | main.rs:63:13:63:22 | source(...) | semmle.label | source(...) | | main.rs:64:16:64:16 | s | semmle.label | s | @@ -91,6 +100,7 @@ testFailures #select | main.rs:28:16:28:21 | sliced | main.rs:26:13:26:22 | source(...) | main.rs:28:16:28:21 | sliced | $@ | main.rs:26:13:26:22 | source(...) | source(...) | | main.rs:38:10:38:11 | s4 | main.rs:32:14:32:23 | source(...) | main.rs:38:10:38:11 | s4 | $@ | main.rs:32:14:32:23 | source(...) | source(...) | +| main.rs:46:10:46:35 | ... + ... | main.rs:43:14:43:23 | source(...) | main.rs:46:10:46:35 | ... + ... | $@ | main.rs:43:14:43:23 | source(...) | source(...) | | main.rs:64:16:64:25 | s.as_str(...) | main.rs:63:13:63:22 | source(...) | main.rs:64:16:64:25 | s.as_str(...) | $@ | main.rs:63:13:63:22 | source(...) | source(...) | | main.rs:71:10:71:19 | formatted1 | main.rs:68:13:68:22 | source(...) | main.rs:71:10:71:19 | formatted1 | $@ | main.rs:68:13:68:22 | source(...) | source(...) | | main.rs:74:10:74:19 | formatted2 | main.rs:68:13:68:22 | source(...) | main.rs:74:10:74:19 | formatted2 | $@ | main.rs:68:13:68:22 | source(...) | source(...) | diff --git a/rust/ql/test/library-tests/dataflow/strings/main.rs b/rust/ql/test/library-tests/dataflow/strings/main.rs index 975fc99ce130..9f86ae0507fd 100644 --- a/rust/ql/test/library-tests/dataflow/strings/main.rs +++ b/rust/ql/test/library-tests/dataflow/strings/main.rs @@ -43,7 +43,7 @@ fn string_add_reference() { let s1 = source(37); let s2 = "1".to_string(); - sink("Hello ".to_string() + &s1); // $ MISSING: hasTaintFlow=37 + sink("Hello ".to_string() + &s1); // $ hasTaintFlow=37 sink("Hello ".to_string() + &s2); } diff --git a/rust/ql/test/query-tests/security/CWE-089/SqlInjection.expected b/rust/ql/test/query-tests/security/CWE-089/SqlInjection.expected index c106f22e7ca7..198ebed2d1a7 100644 --- a/rust/ql/test/query-tests/security/CWE-089/SqlInjection.expected +++ b/rust/ql/test/query-tests/security/CWE-089/SqlInjection.expected @@ -1,13 +1,36 @@ #select +| sqlx.rs:65:30:65:52 | unsafe_query_2.as_str(...) | sqlx.rs:48:25:48:46 | ...::get | sqlx.rs:65:30:65:52 | unsafe_query_2.as_str(...) | This query depends on a $@. | sqlx.rs:48:25:48:46 | ...::get | user-provided value | +| sqlx.rs:66:30:66:52 | unsafe_query_3.as_str(...) | sqlx.rs:48:25:48:46 | ...::get | sqlx.rs:66:30:66:52 | unsafe_query_3.as_str(...) | This query depends on a $@. | sqlx.rs:48:25:48:46 | ...::get | user-provided value | | sqlx.rs:67:30:67:52 | unsafe_query_4.as_str(...) | sqlx.rs:48:25:48:46 | ...::get | sqlx.rs:67:30:67:52 | unsafe_query_4.as_str(...) | This query depends on a $@. | sqlx.rs:48:25:48:46 | ...::get | user-provided value | +| sqlx.rs:76:29:76:51 | unsafe_query_2.as_str(...) | sqlx.rs:48:25:48:46 | ...::get | sqlx.rs:76:29:76:51 | unsafe_query_2.as_str(...) | This query depends on a $@. | sqlx.rs:48:25:48:46 | ...::get | user-provided value | +| sqlx.rs:77:29:77:51 | unsafe_query_3.as_str(...) | sqlx.rs:48:25:48:46 | ...::get | sqlx.rs:77:29:77:51 | unsafe_query_3.as_str(...) | This query depends on a $@. | sqlx.rs:48:25:48:46 | ...::get | user-provided value | | sqlx.rs:78:29:78:51 | unsafe_query_4.as_str(...) | sqlx.rs:48:25:48:46 | ...::get | sqlx.rs:78:29:78:51 | unsafe_query_4.as_str(...) | This query depends on a $@. | sqlx.rs:48:25:48:46 | ...::get | user-provided value | +| sqlx.rs:104:30:104:52 | unsafe_query_1.as_str(...) | sqlx.rs:96:25:96:46 | ...::get | sqlx.rs:104:30:104:52 | unsafe_query_1.as_str(...) | This query depends on a $@. | sqlx.rs:96:25:96:46 | ...::get | user-provided value | +| sqlx.rs:109:31:109:53 | unsafe_query_1.as_str(...) | sqlx.rs:96:25:96:46 | ...::get | sqlx.rs:109:31:109:53 | unsafe_query_1.as_str(...) | This query depends on a $@. | sqlx.rs:96:25:96:46 | ...::get | user-provided value | +| sqlx.rs:116:29:116:51 | unsafe_query_1.as_str(...) | sqlx.rs:96:25:96:46 | ...::get | sqlx.rs:116:29:116:51 | unsafe_query_1.as_str(...) | This query depends on a $@. | sqlx.rs:96:25:96:46 | ...::get | user-provided value | +| sqlx.rs:123:29:123:51 | unsafe_query_1.as_str(...) | sqlx.rs:96:25:96:46 | ...::get | sqlx.rs:123:29:123:51 | unsafe_query_1.as_str(...) | This query depends on a $@. | sqlx.rs:96:25:96:46 | ...::get | user-provided value | +| sqlx.rs:132:55:132:77 | unsafe_query_1.as_str(...) | sqlx.rs:96:25:96:46 | ...::get | sqlx.rs:132:55:132:77 | unsafe_query_1.as_str(...) | This query depends on a $@. | sqlx.rs:96:25:96:46 | ...::get | user-provided value | +| sqlx.rs:141:55:141:77 | unsafe_query_1.as_str(...) | sqlx.rs:96:25:96:46 | ...::get | sqlx.rs:141:55:141:77 | unsafe_query_1.as_str(...) | This query depends on a $@. | sqlx.rs:96:25:96:46 | ...::get | user-provided value | +| sqlx.rs:149:29:149:51 | unsafe_query_1.as_str(...) | sqlx.rs:96:25:96:46 | ...::get | sqlx.rs:149:29:149:51 | unsafe_query_1.as_str(...) | This query depends on a $@. | sqlx.rs:96:25:96:46 | ...::get | user-provided value | +| sqlx.rs:177:30:177:52 | unsafe_query_1.as_str(...) | sqlx.rs:169:25:169:46 | ...::get | sqlx.rs:177:30:177:52 | unsafe_query_1.as_str(...) | This query depends on a $@. | sqlx.rs:169:25:169:46 | ...::get | user-provided value | +| sqlx.rs:184:29:184:51 | unsafe_query_1.as_str(...) | sqlx.rs:169:25:169:46 | ...::get | sqlx.rs:184:29:184:51 | unsafe_query_1.as_str(...) | This query depends on a $@. | sqlx.rs:169:25:169:46 | ...::get | user-provided value | edges +| sqlx.rs:48:9:48:21 | remote_string | sqlx.rs:54:27:54:39 | remote_string | provenance | | +| sqlx.rs:48:9:48:21 | remote_string | sqlx.rs:55:84:55:96 | remote_string | provenance | | | sqlx.rs:48:9:48:21 | remote_string | sqlx.rs:56:34:56:89 | MacroExpr | provenance | | | sqlx.rs:48:25:48:46 | ...::get | sqlx.rs:48:25:48:69 | ...::get(...) [Ok] | provenance | Src:MaD:1 | | sqlx.rs:48:25:48:69 | ...::get(...) [Ok] | sqlx.rs:48:25:48:78 | ... .unwrap(...) | provenance | MaD:4 | | sqlx.rs:48:25:48:78 | ... .unwrap(...) | sqlx.rs:48:25:48:85 | ... .text(...) [Ok] | provenance | MaD:7 | | sqlx.rs:48:25:48:85 | ... .text(...) [Ok] | sqlx.rs:48:25:48:118 | ... .unwrap_or(...) | provenance | MaD:5 | | sqlx.rs:48:25:48:118 | ... .unwrap_or(...) | sqlx.rs:48:9:48:21 | remote_string | provenance | | +| sqlx.rs:54:9:54:22 | unsafe_query_2 [&ref] | sqlx.rs:65:30:65:43 | unsafe_query_2 [&ref] | provenance | | +| sqlx.rs:54:9:54:22 | unsafe_query_2 [&ref] | sqlx.rs:76:29:76:42 | unsafe_query_2 [&ref] | provenance | | +| sqlx.rs:54:26:54:39 | &remote_string [&ref] | sqlx.rs:54:9:54:22 | unsafe_query_2 [&ref] | provenance | | +| sqlx.rs:54:27:54:39 | remote_string | sqlx.rs:54:26:54:39 | &remote_string [&ref] | provenance | | +| sqlx.rs:55:9:55:22 | unsafe_query_3 | sqlx.rs:66:30:66:43 | unsafe_query_3 | provenance | | +| sqlx.rs:55:9:55:22 | unsafe_query_3 | sqlx.rs:77:29:77:42 | unsafe_query_3 | provenance | | +| sqlx.rs:55:83:55:96 | &remote_string [&ref] | sqlx.rs:55:9:55:22 | unsafe_query_3 | provenance | | +| sqlx.rs:55:84:55:96 | remote_string | sqlx.rs:55:83:55:96 | &remote_string [&ref] | provenance | | | sqlx.rs:56:9:56:22 | unsafe_query_4 | sqlx.rs:67:30:67:43 | unsafe_query_4 | provenance | | | sqlx.rs:56:9:56:22 | unsafe_query_4 | sqlx.rs:78:29:78:42 | unsafe_query_4 | provenance | | | sqlx.rs:56:26:56:90 | res | sqlx.rs:56:34:56:89 | { ... } | provenance | | @@ -15,8 +38,46 @@ edges | sqlx.rs:56:34:56:89 | ...::must_use(...) | sqlx.rs:56:9:56:22 | unsafe_query_4 | provenance | | | sqlx.rs:56:34:56:89 | MacroExpr | sqlx.rs:56:34:56:89 | ...::format(...) | provenance | MaD:3 | | sqlx.rs:56:34:56:89 | { ... } | sqlx.rs:56:34:56:89 | ...::must_use(...) | provenance | MaD:6 | +| sqlx.rs:65:30:65:43 | unsafe_query_2 [&ref] | sqlx.rs:65:30:65:52 | unsafe_query_2.as_str(...) | provenance | MaD:2 | +| sqlx.rs:66:30:66:43 | unsafe_query_3 | sqlx.rs:66:30:66:52 | unsafe_query_3.as_str(...) | provenance | MaD:2 | | sqlx.rs:67:30:67:43 | unsafe_query_4 | sqlx.rs:67:30:67:52 | unsafe_query_4.as_str(...) | provenance | MaD:2 | +| sqlx.rs:76:29:76:42 | unsafe_query_2 [&ref] | sqlx.rs:76:29:76:51 | unsafe_query_2.as_str(...) | provenance | MaD:2 | +| sqlx.rs:77:29:77:42 | unsafe_query_3 | sqlx.rs:77:29:77:51 | unsafe_query_3.as_str(...) | provenance | MaD:2 | | sqlx.rs:78:29:78:42 | unsafe_query_4 | sqlx.rs:78:29:78:51 | unsafe_query_4.as_str(...) | provenance | MaD:2 | +| sqlx.rs:96:9:96:21 | remote_string | sqlx.rs:98:84:98:96 | remote_string | provenance | | +| sqlx.rs:96:25:96:46 | ...::get | sqlx.rs:96:25:96:69 | ...::get(...) [Ok] | provenance | Src:MaD:1 | +| sqlx.rs:96:25:96:69 | ...::get(...) [Ok] | sqlx.rs:96:25:96:78 | ... .unwrap(...) | provenance | MaD:4 | +| sqlx.rs:96:25:96:78 | ... .unwrap(...) | sqlx.rs:96:25:96:85 | ... .text(...) [Ok] | provenance | MaD:7 | +| sqlx.rs:96:25:96:85 | ... .text(...) [Ok] | sqlx.rs:96:25:96:118 | ... .unwrap_or(...) | provenance | MaD:5 | +| sqlx.rs:96:25:96:118 | ... .unwrap_or(...) | sqlx.rs:96:9:96:21 | remote_string | provenance | | +| sqlx.rs:98:9:98:22 | unsafe_query_1 | sqlx.rs:104:30:104:43 | unsafe_query_1 | provenance | | +| sqlx.rs:98:9:98:22 | unsafe_query_1 | sqlx.rs:109:31:109:44 | unsafe_query_1 | provenance | | +| sqlx.rs:98:9:98:22 | unsafe_query_1 | sqlx.rs:116:29:116:42 | unsafe_query_1 | provenance | | +| sqlx.rs:98:9:98:22 | unsafe_query_1 | sqlx.rs:123:29:123:42 | unsafe_query_1 | provenance | | +| sqlx.rs:98:9:98:22 | unsafe_query_1 | sqlx.rs:132:55:132:68 | unsafe_query_1 | provenance | | +| sqlx.rs:98:9:98:22 | unsafe_query_1 | sqlx.rs:141:55:141:68 | unsafe_query_1 | provenance | | +| sqlx.rs:98:9:98:22 | unsafe_query_1 | sqlx.rs:149:29:149:42 | unsafe_query_1 | provenance | | +| sqlx.rs:98:83:98:96 | &remote_string [&ref] | sqlx.rs:98:9:98:22 | unsafe_query_1 | provenance | | +| sqlx.rs:98:84:98:96 | remote_string | sqlx.rs:98:83:98:96 | &remote_string [&ref] | provenance | | +| sqlx.rs:104:30:104:43 | unsafe_query_1 | sqlx.rs:104:30:104:52 | unsafe_query_1.as_str(...) | provenance | MaD:2 | +| sqlx.rs:109:31:109:44 | unsafe_query_1 | sqlx.rs:109:31:109:53 | unsafe_query_1.as_str(...) | provenance | MaD:2 | +| sqlx.rs:116:29:116:42 | unsafe_query_1 | sqlx.rs:116:29:116:51 | unsafe_query_1.as_str(...) | provenance | MaD:2 | +| sqlx.rs:123:29:123:42 | unsafe_query_1 | sqlx.rs:123:29:123:51 | unsafe_query_1.as_str(...) | provenance | MaD:2 | +| sqlx.rs:132:55:132:68 | unsafe_query_1 | sqlx.rs:132:55:132:77 | unsafe_query_1.as_str(...) | provenance | MaD:2 | +| sqlx.rs:141:55:141:68 | unsafe_query_1 | sqlx.rs:141:55:141:77 | unsafe_query_1.as_str(...) | provenance | MaD:2 | +| sqlx.rs:149:29:149:42 | unsafe_query_1 | sqlx.rs:149:29:149:51 | unsafe_query_1.as_str(...) | provenance | MaD:2 | +| sqlx.rs:169:9:169:21 | remote_string | sqlx.rs:171:84:171:96 | remote_string | provenance | | +| sqlx.rs:169:25:169:46 | ...::get | sqlx.rs:169:25:169:69 | ...::get(...) [Ok] | provenance | Src:MaD:1 | +| sqlx.rs:169:25:169:69 | ...::get(...) [Ok] | sqlx.rs:169:25:169:78 | ... .unwrap(...) | provenance | MaD:4 | +| sqlx.rs:169:25:169:78 | ... .unwrap(...) | sqlx.rs:169:25:169:85 | ... .text(...) [Ok] | provenance | MaD:7 | +| sqlx.rs:169:25:169:85 | ... .text(...) [Ok] | sqlx.rs:169:25:169:118 | ... .unwrap_or(...) | provenance | MaD:5 | +| sqlx.rs:169:25:169:118 | ... .unwrap_or(...) | sqlx.rs:169:9:169:21 | remote_string | provenance | | +| sqlx.rs:171:9:171:22 | unsafe_query_1 | sqlx.rs:177:30:177:43 | unsafe_query_1 | provenance | | +| sqlx.rs:171:9:171:22 | unsafe_query_1 | sqlx.rs:184:29:184:42 | unsafe_query_1 | provenance | | +| sqlx.rs:171:83:171:96 | &remote_string [&ref] | sqlx.rs:171:9:171:22 | unsafe_query_1 | provenance | | +| sqlx.rs:171:84:171:96 | remote_string | sqlx.rs:171:83:171:96 | &remote_string [&ref] | provenance | | +| sqlx.rs:177:30:177:43 | unsafe_query_1 | sqlx.rs:177:30:177:52 | unsafe_query_1.as_str(...) | provenance | MaD:2 | +| sqlx.rs:184:29:184:42 | unsafe_query_1 | sqlx.rs:184:29:184:51 | unsafe_query_1.as_str(...) | provenance | MaD:2 | models | 1 | Source: repo:https://github.com/seanmonstar/reqwest:reqwest; crate::blocking::get; remote; ReturnValue.Variant[crate::result::Result::Ok(0)] | | 2 | Summary: lang:alloc; ::as_str; Argument[self]; ReturnValue; taint | @@ -32,14 +93,64 @@ nodes | sqlx.rs:48:25:48:78 | ... .unwrap(...) | semmle.label | ... .unwrap(...) | | sqlx.rs:48:25:48:85 | ... .text(...) [Ok] | semmle.label | ... .text(...) [Ok] | | sqlx.rs:48:25:48:118 | ... .unwrap_or(...) | semmle.label | ... .unwrap_or(...) | +| sqlx.rs:54:9:54:22 | unsafe_query_2 [&ref] | semmle.label | unsafe_query_2 [&ref] | +| sqlx.rs:54:26:54:39 | &remote_string [&ref] | semmle.label | &remote_string [&ref] | +| sqlx.rs:54:27:54:39 | remote_string | semmle.label | remote_string | +| sqlx.rs:55:9:55:22 | unsafe_query_3 | semmle.label | unsafe_query_3 | +| sqlx.rs:55:83:55:96 | &remote_string [&ref] | semmle.label | &remote_string [&ref] | +| sqlx.rs:55:84:55:96 | remote_string | semmle.label | remote_string | | sqlx.rs:56:9:56:22 | unsafe_query_4 | semmle.label | unsafe_query_4 | | sqlx.rs:56:26:56:90 | res | semmle.label | res | | sqlx.rs:56:34:56:89 | ...::format(...) | semmle.label | ...::format(...) | | sqlx.rs:56:34:56:89 | ...::must_use(...) | semmle.label | ...::must_use(...) | | sqlx.rs:56:34:56:89 | MacroExpr | semmle.label | MacroExpr | | sqlx.rs:56:34:56:89 | { ... } | semmle.label | { ... } | +| sqlx.rs:65:30:65:43 | unsafe_query_2 [&ref] | semmle.label | unsafe_query_2 [&ref] | +| sqlx.rs:65:30:65:52 | unsafe_query_2.as_str(...) | semmle.label | unsafe_query_2.as_str(...) | +| sqlx.rs:66:30:66:43 | unsafe_query_3 | semmle.label | unsafe_query_3 | +| sqlx.rs:66:30:66:52 | unsafe_query_3.as_str(...) | semmle.label | unsafe_query_3.as_str(...) | | sqlx.rs:67:30:67:43 | unsafe_query_4 | semmle.label | unsafe_query_4 | | sqlx.rs:67:30:67:52 | unsafe_query_4.as_str(...) | semmle.label | unsafe_query_4.as_str(...) | +| sqlx.rs:76:29:76:42 | unsafe_query_2 [&ref] | semmle.label | unsafe_query_2 [&ref] | +| sqlx.rs:76:29:76:51 | unsafe_query_2.as_str(...) | semmle.label | unsafe_query_2.as_str(...) | +| sqlx.rs:77:29:77:42 | unsafe_query_3 | semmle.label | unsafe_query_3 | +| sqlx.rs:77:29:77:51 | unsafe_query_3.as_str(...) | semmle.label | unsafe_query_3.as_str(...) | | sqlx.rs:78:29:78:42 | unsafe_query_4 | semmle.label | unsafe_query_4 | | sqlx.rs:78:29:78:51 | unsafe_query_4.as_str(...) | semmle.label | unsafe_query_4.as_str(...) | +| sqlx.rs:96:9:96:21 | remote_string | semmle.label | remote_string | +| sqlx.rs:96:25:96:46 | ...::get | semmle.label | ...::get | +| sqlx.rs:96:25:96:69 | ...::get(...) [Ok] | semmle.label | ...::get(...) [Ok] | +| sqlx.rs:96:25:96:78 | ... .unwrap(...) | semmle.label | ... .unwrap(...) | +| sqlx.rs:96:25:96:85 | ... .text(...) [Ok] | semmle.label | ... .text(...) [Ok] | +| sqlx.rs:96:25:96:118 | ... .unwrap_or(...) | semmle.label | ... .unwrap_or(...) | +| sqlx.rs:98:9:98:22 | unsafe_query_1 | semmle.label | unsafe_query_1 | +| sqlx.rs:98:83:98:96 | &remote_string [&ref] | semmle.label | &remote_string [&ref] | +| sqlx.rs:98:84:98:96 | remote_string | semmle.label | remote_string | +| sqlx.rs:104:30:104:43 | unsafe_query_1 | semmle.label | unsafe_query_1 | +| sqlx.rs:104:30:104:52 | unsafe_query_1.as_str(...) | semmle.label | unsafe_query_1.as_str(...) | +| sqlx.rs:109:31:109:44 | unsafe_query_1 | semmle.label | unsafe_query_1 | +| sqlx.rs:109:31:109:53 | unsafe_query_1.as_str(...) | semmle.label | unsafe_query_1.as_str(...) | +| sqlx.rs:116:29:116:42 | unsafe_query_1 | semmle.label | unsafe_query_1 | +| sqlx.rs:116:29:116:51 | unsafe_query_1.as_str(...) | semmle.label | unsafe_query_1.as_str(...) | +| sqlx.rs:123:29:123:42 | unsafe_query_1 | semmle.label | unsafe_query_1 | +| sqlx.rs:123:29:123:51 | unsafe_query_1.as_str(...) | semmle.label | unsafe_query_1.as_str(...) | +| sqlx.rs:132:55:132:68 | unsafe_query_1 | semmle.label | unsafe_query_1 | +| sqlx.rs:132:55:132:77 | unsafe_query_1.as_str(...) | semmle.label | unsafe_query_1.as_str(...) | +| sqlx.rs:141:55:141:68 | unsafe_query_1 | semmle.label | unsafe_query_1 | +| sqlx.rs:141:55:141:77 | unsafe_query_1.as_str(...) | semmle.label | unsafe_query_1.as_str(...) | +| sqlx.rs:149:29:149:42 | unsafe_query_1 | semmle.label | unsafe_query_1 | +| sqlx.rs:149:29:149:51 | unsafe_query_1.as_str(...) | semmle.label | unsafe_query_1.as_str(...) | +| sqlx.rs:169:9:169:21 | remote_string | semmle.label | remote_string | +| sqlx.rs:169:25:169:46 | ...::get | semmle.label | ...::get | +| sqlx.rs:169:25:169:69 | ...::get(...) [Ok] | semmle.label | ...::get(...) [Ok] | +| sqlx.rs:169:25:169:78 | ... .unwrap(...) | semmle.label | ... .unwrap(...) | +| sqlx.rs:169:25:169:85 | ... .text(...) [Ok] | semmle.label | ... .text(...) [Ok] | +| sqlx.rs:169:25:169:118 | ... .unwrap_or(...) | semmle.label | ... .unwrap_or(...) | +| sqlx.rs:171:9:171:22 | unsafe_query_1 | semmle.label | unsafe_query_1 | +| sqlx.rs:171:83:171:96 | &remote_string [&ref] | semmle.label | &remote_string [&ref] | +| sqlx.rs:171:84:171:96 | remote_string | semmle.label | remote_string | +| sqlx.rs:177:30:177:43 | unsafe_query_1 | semmle.label | unsafe_query_1 | +| sqlx.rs:177:30:177:52 | unsafe_query_1.as_str(...) | semmle.label | unsafe_query_1.as_str(...) | +| sqlx.rs:184:29:184:42 | unsafe_query_1 | semmle.label | unsafe_query_1 | +| sqlx.rs:184:29:184:51 | unsafe_query_1.as_str(...) | semmle.label | unsafe_query_1.as_str(...) | subpaths diff --git a/rust/ql/test/query-tests/security/CWE-089/sqlx.rs b/rust/ql/test/query-tests/security/CWE-089/sqlx.rs index 24d3e585e95b..4fb1ccd1c187 100644 --- a/rust/ql/test/query-tests/security/CWE-089/sqlx.rs +++ b/rust/ql/test/query-tests/security/CWE-089/sqlx.rs @@ -62,8 +62,8 @@ async fn test_sqlx_mysql(url: &str, enable_remote: bool) -> Result<(), sqlx::Err let _ = conn.execute(safe_query_3.as_str()).await?; // $ sql-sink let _ = conn.execute(unsafe_query_1.as_str()).await?; // $ sql-sink MISSING: Alert[rust/sql-injection]=args1 if enable_remote { - let _ = conn.execute(unsafe_query_2.as_str()).await?; // $ sql-sink MISSING: Alert[rust/sql-injection]=remote1 - let _ = conn.execute(unsafe_query_3.as_str()).await?; // $ sql-sink MISSING: Alert[rust/sql-injection]=remote1 + let _ = conn.execute(unsafe_query_2.as_str()).await?; // $ sql-sink Alert[rust/sql-injection]=remote1 + let _ = conn.execute(unsafe_query_3.as_str()).await?; // $ sql-sink Alert[rust/sql-injection]=remote1 let _ = conn.execute(unsafe_query_4.as_str()).await?; // $ sql-sink Alert[rust/sql-injection]=remote1 } @@ -73,8 +73,8 @@ async fn test_sqlx_mysql(url: &str, enable_remote: bool) -> Result<(), sqlx::Err let _ = sqlx::query(safe_query_3.as_str()).execute(&pool).await?; // $ sql-sink let _ = sqlx::query(unsafe_query_1.as_str()).execute(&pool).await?; // $ sql-sink MISSING: Alert[rust/sql-injection][rust/sql-injection]=args1 if enable_remote { - let _ = sqlx::query(unsafe_query_2.as_str()).execute(&pool).await?; // $ sql-sink MISSING: Alert[rust/sql-injection]=remote1 - let _ = sqlx::query(unsafe_query_3.as_str()).execute(&pool).await?; // $ sql-sink MISSING: Alert[rust/sql-injection]=remote1 + let _ = sqlx::query(unsafe_query_2.as_str()).execute(&pool).await?; // $ sql-sink Alert[rust/sql-injection]=remote1 + let _ = sqlx::query(unsafe_query_3.as_str()).execute(&pool).await?; // $ sql-sink Alert[rust/sql-injection]=remote1 let _ = sqlx::query(unsafe_query_4.as_str()).execute(&pool).await?; // $ sql-sink Alert[rust/sql-injection]=remote1 } let _ = sqlx::query(prepared_query_1.as_str()).bind(const_string).execute(&pool).await?; // $ sql-sink @@ -93,7 +93,7 @@ async fn test_sqlx_sqlite(url: &str, enable_remote: bool) -> Result<(), sqlx::Er // construct queries let const_string = String::from("Alice"); - let remote_string = reqwest::blocking::get("http://example.com/").unwrap().text().unwrap_or(String::from("Alice")); // $ MISSING: Source=remote2 + let remote_string = reqwest::blocking::get("http://example.com/").unwrap().text().unwrap_or(String::from("Alice")); // $ Source=remote2 let safe_query_1 = String::from("SELECT * FROM people WHERE firstname='") + &const_string + "'"; let unsafe_query_1 = String::from("SELECT * FROM people WHERE firstname='") + &remote_string + "'"; let prepared_query_1 = String::from("SELECT * FROM people WHERE firstname=?"); // (prepared arguments are safe) @@ -101,26 +101,26 @@ async fn test_sqlx_sqlite(url: &str, enable_remote: bool) -> Result<(), sqlx::Er // direct execution (with extra variants) let _ = conn.execute(safe_query_1.as_str()).await?; // $ sql-sink if enable_remote { - let _ = conn.execute(unsafe_query_1.as_str()).await?; // $ sql-sink MISSING: Alert[rust/sql-injection]=remote2 + let _ = conn.execute(unsafe_query_1.as_str()).await?; // $ sql-sink Alert[rust/sql-injection]=remote2 } // ... let _ = sqlx::raw_sql(safe_query_1.as_str()).execute(&mut conn).await?; // $ sql-sink if enable_remote { - let _ = sqlx::raw_sql(unsafe_query_1.as_str()).execute(&mut conn).await?; // $ sql-sink MISSING: Alert[rust/sql-injection]=remote2 + let _ = sqlx::raw_sql(unsafe_query_1.as_str()).execute(&mut conn).await?; // $ sql-sink Alert[rust/sql-injection]=remote2 } // prepared queries (with extra variants) let _ = sqlx::query(safe_query_1.as_str()).execute(&mut conn).await?; // $ sql-sink let _ = sqlx::query(prepared_query_1.as_str()).bind(&const_string).execute(&mut conn).await?; // $ sql-sink if enable_remote { - let _ = sqlx::query(unsafe_query_1.as_str()).execute(&mut conn).await?; // $ sql-sink MISSING: Alert[rust/sql-injection]=remote2 + let _ = sqlx::query(unsafe_query_1.as_str()).execute(&mut conn).await?; // $ sql-sink Alert[rust/sql-injection]=remote2 let _ = sqlx::query(prepared_query_1.as_str()).bind(&remote_string).execute(&mut conn).await?; // $ sql-sink } // ... let _ = sqlx::query(safe_query_1.as_str()).fetch(&mut conn); // $ sql-sink let _ = sqlx::query(prepared_query_1.as_str()).bind(&const_string).fetch(&mut conn); // $ sql-sink if enable_remote { - let _ = sqlx::query(unsafe_query_1.as_str()).fetch(&mut conn); // $ sql-sink MISSING: Alert[rust/sql-injection]=remote2 + let _ = sqlx::query(unsafe_query_1.as_str()).fetch(&mut conn); // $ sql-sink Alert[rust/sql-injection]=remote2 let _ = sqlx::query(prepared_query_1.as_str()).bind(&remote_string).fetch(&mut conn); // $ sql-sink } // ... @@ -129,7 +129,7 @@ async fn test_sqlx_sqlite(url: &str, enable_remote: bool) -> Result<(), sqlx::Er let row2: (i64, String, String) = sqlx::query_as(prepared_query_1.as_str()).bind(&const_string).fetch_one(&mut conn).await?; // $ sql-sink println!(" row2 = {:?}", row2); if enable_remote { - let _: (i64, String, String) = sqlx::query_as(unsafe_query_1.as_str()).fetch_one(&mut conn).await?; // $ sql-sink MISSING: Alert[rust/sql-injection]=remote2 + let _: (i64, String, String) = sqlx::query_as(unsafe_query_1.as_str()).fetch_one(&mut conn).await?; // $ sql-sink Alert[rust/sql-injection]=remote2 let _: (i64, String, String) = sqlx::query_as(prepared_query_1.as_str()).bind(&remote_string).fetch_one(&mut conn).await?; // $ sql-sink } // ... @@ -138,7 +138,7 @@ async fn test_sqlx_sqlite(url: &str, enable_remote: bool) -> Result<(), sqlx::Er let row4: (i64, String, String) = sqlx::query_as(prepared_query_1.as_str()).bind(&const_string).fetch_optional(&mut conn).await?.expect("no data"); // $ sql-sink println!(" row4 = {:?}", row4); if enable_remote { - let _: (i64, String, String) = sqlx::query_as(unsafe_query_1.as_str()).fetch_optional(&mut conn).await?.expect("no data"); // $ sql-sink $ MISSING: Alert[rust/sql-injection]=remote2 + let _: (i64, String, String) = sqlx::query_as(unsafe_query_1.as_str()).fetch_optional(&mut conn).await?.expect("no data"); // $ sql-sink $ Alert[rust/sql-injection]=remote2 let _: (i64, String, String) = sqlx::query_as(prepared_query_1.as_str()).bind(&remote_string).fetch_optional(&mut conn).await?.expect("no data"); // $ sql-sink } // ... @@ -146,7 +146,7 @@ async fn test_sqlx_sqlite(url: &str, enable_remote: bool) -> Result<(), sqlx::Er let _ = sqlx::query(prepared_query_1.as_str()).bind(&const_string).fetch_all(&mut conn).await?; // $ sql-sink let _ = sqlx::query("SELECT * FROM people WHERE firstname=?").bind(&const_string).fetch_all(&mut conn).await?; // $ sql-sink if enable_remote { - let _ = sqlx::query(unsafe_query_1.as_str()).fetch_all(&mut conn).await?; // $ sql-sink MISSING: Alert[rust/sql-injection]=remote2 + let _ = sqlx::query(unsafe_query_1.as_str()).fetch_all(&mut conn).await?; // $ sql-sink Alert[rust/sql-injection]=remote2 let _ = sqlx::query(prepared_query_1.as_str()).bind(&remote_string).fetch_all(&mut conn).await?; // $ sql-sink let _ = sqlx::query("SELECT * FROM people WHERE firstname=?").bind(&remote_string).fetch_all(&mut conn).await?; // $ sql-sink } @@ -166,7 +166,7 @@ async fn test_sqlx_postgres(url: &str, enable_remote: bool) -> Result<(), sqlx:: // construct queries let const_string = String::from("Alice"); - let remote_string = reqwest::blocking::get("http://example.com/").unwrap().text().unwrap_or(String::from("Alice")); // $ MISSING: Source=remote3 + let remote_string = reqwest::blocking::get("http://example.com/").unwrap().text().unwrap_or(String::from("Alice")); // $ Source=remote3 let safe_query_1 = String::from("SELECT * FROM people WHERE firstname='") + &const_string + "'"; let unsafe_query_1 = String::from("SELECT * FROM people WHERE firstname='") + &remote_string + "'"; let prepared_query_1 = String::from("SELECT * FROM people WHERE firstname=$1"); // (prepared arguments are safe) @@ -174,14 +174,14 @@ async fn test_sqlx_postgres(url: &str, enable_remote: bool) -> Result<(), sqlx:: // direct execution let _ = conn.execute(safe_query_1.as_str()).await?; // $ sql-sink if enable_remote { - let _ = conn.execute(unsafe_query_1.as_str()).await?; // $ sql-sink MISSING: Alert[rust/sql-injection]=remote3 + let _ = conn.execute(unsafe_query_1.as_str()).await?; // $ sql-sink Alert[rust/sql-injection]=remote3 } // prepared queries let _ = sqlx::query(safe_query_1.as_str()).execute(&pool).await?; // $ sql-sink let _ = sqlx::query(prepared_query_1.as_str()).bind(&const_string).execute(&pool).await?; // $ sql-sink if enable_remote { - let _ = sqlx::query(unsafe_query_1.as_str()).execute(&pool).await?; // $ sql-sink MISSING: Alert[rust/sql-injection]=remote3 + let _ = sqlx::query(unsafe_query_1.as_str()).execute(&pool).await?; // $ sql-sink Alert[rust/sql-injection]=remote3 let _ = sqlx::query(prepared_query_1.as_str()).bind(&remote_string).execute(&pool).await?; // $ sql-sink } diff --git a/rust/ql/test/query-tests/security/CWE-312/CleartextLogging.expected b/rust/ql/test/query-tests/security/CWE-312/CleartextLogging.expected index 517e420a994d..32f553ff9d27 100644 --- a/rust/ql/test/query-tests/security/CWE-312/CleartextLogging.expected +++ b/rust/ql/test/query-tests/security/CWE-312/CleartextLogging.expected @@ -125,12 +125,18 @@ edges | test_logging.rs:86:20:86:43 | MacroExpr | test_logging.rs:86:5:86:44 | ...::log::<...> | provenance | MaD:9 Sink:MaD:9 | | test_logging.rs:86:36:86:43 | password | test_logging.rs:86:20:86:43 | MacroExpr | provenance | | | test_logging.rs:93:9:93:10 | m1 | test_logging.rs:94:11:94:28 | MacroExpr | provenance | | +| test_logging.rs:93:9:93:10 | m1 [&ref] | test_logging.rs:94:27:94:28 | m1 [&ref] | provenance | | | test_logging.rs:93:14:93:22 | &password | test_logging.rs:93:9:93:10 | m1 | provenance | | +| test_logging.rs:93:14:93:22 | &password [&ref] | test_logging.rs:93:9:93:10 | m1 [&ref] | provenance | | | test_logging.rs:93:15:93:22 | password | test_logging.rs:93:14:93:22 | &password | provenance | Config | +| test_logging.rs:93:15:93:22 | password | test_logging.rs:93:14:93:22 | &password [&ref] | provenance | | | test_logging.rs:94:11:94:28 | MacroExpr | test_logging.rs:94:5:94:29 | ...::log | provenance | MaD:9 Sink:MaD:9 | +| test_logging.rs:94:27:94:28 | m1 [&ref] | test_logging.rs:94:11:94:28 | MacroExpr | provenance | | | test_logging.rs:96:9:96:10 | m2 | test_logging.rs:97:11:97:18 | MacroExpr | provenance | | | test_logging.rs:96:41:96:49 | &password | test_logging.rs:96:9:96:10 | m2 | provenance | | +| test_logging.rs:96:41:96:49 | &password [&ref] | test_logging.rs:96:9:96:10 | m2 | provenance | | | test_logging.rs:96:42:96:49 | password | test_logging.rs:96:41:96:49 | &password | provenance | Config | +| test_logging.rs:96:42:96:49 | password | test_logging.rs:96:41:96:49 | &password [&ref] | provenance | | | test_logging.rs:97:11:97:18 | MacroExpr | test_logging.rs:97:5:97:19 | ...::log | provenance | MaD:9 Sink:MaD:9 | | test_logging.rs:99:9:99:10 | m3 | test_logging.rs:100:11:100:18 | MacroExpr | provenance | | | test_logging.rs:99:14:99:46 | res | test_logging.rs:99:22:99:45 | { ... } | provenance | | @@ -329,12 +335,16 @@ nodes | test_logging.rs:86:20:86:43 | MacroExpr | semmle.label | MacroExpr | | test_logging.rs:86:36:86:43 | password | semmle.label | password | | test_logging.rs:93:9:93:10 | m1 | semmle.label | m1 | +| test_logging.rs:93:9:93:10 | m1 [&ref] | semmle.label | m1 [&ref] | | test_logging.rs:93:14:93:22 | &password | semmle.label | &password | +| test_logging.rs:93:14:93:22 | &password [&ref] | semmle.label | &password [&ref] | | test_logging.rs:93:15:93:22 | password | semmle.label | password | | test_logging.rs:94:5:94:29 | ...::log | semmle.label | ...::log | | test_logging.rs:94:11:94:28 | MacroExpr | semmle.label | MacroExpr | +| test_logging.rs:94:27:94:28 | m1 [&ref] | semmle.label | m1 [&ref] | | test_logging.rs:96:9:96:10 | m2 | semmle.label | m2 | | test_logging.rs:96:41:96:49 | &password | semmle.label | &password | +| test_logging.rs:96:41:96:49 | &password [&ref] | semmle.label | &password [&ref] | | test_logging.rs:96:42:96:49 | password | semmle.label | password | | test_logging.rs:97:5:97:19 | ...::log | semmle.label | ...::log | | test_logging.rs:97:11:97:18 | MacroExpr | semmle.label | MacroExpr | diff --git a/shared/dataflow/codeql/dataflow/TaintTracking.qll b/shared/dataflow/codeql/dataflow/TaintTracking.qll index b08f1e4af469..1a9959a8dc56 100644 --- a/shared/dataflow/codeql/dataflow/TaintTracking.qll +++ b/shared/dataflow/codeql/dataflow/TaintTracking.qll @@ -71,7 +71,8 @@ module TaintFlowMake< Config::isSink(node) or Config::isSink(node, _) or Config::isAdditionalFlowStep(node, _, _) or - Config::isAdditionalFlowStep(node, _, _, _, _) + Config::isAdditionalFlowStep(node, _, _, _, _) or + defaultAdditionalTaintStep(node, _, _) ) and defaultImplicitTaintRead(node, c) } diff --git a/swift/ql/test/library-tests/dataflow/taint/core/Taint.expected b/swift/ql/test/library-tests/dataflow/taint/core/Taint.expected index 7563f2173553..f508a74e58ff 100644 --- a/swift/ql/test/library-tests/dataflow/taint/core/Taint.expected +++ b/swift/ql/test/library-tests/dataflow/taint/core/Taint.expected @@ -13,7 +13,9 @@ edges | conversions.swift:46:19:46:39 | call to sourceInt(_:) | conversions.swift:46:12:46:40 | call to Double.init(_:) | provenance | | | conversions.swift:47:19:47:39 | call to sourceInt(_:) | conversions.swift:47:12:47:40 | call to String.init(_:) | provenance | | | conversions.swift:48:12:48:40 | call to String.init(_:) | conversions.swift:48:12:48:42 | .utf8 | provenance | | +| conversions.swift:48:12:48:40 | call to String.init(_:) [Collection element] | conversions.swift:48:12:48:42 | .utf8 | provenance | | | conversions.swift:48:19:48:39 | call to sourceInt(_:) | conversions.swift:48:12:48:40 | call to String.init(_:) | provenance | | +| conversions.swift:48:19:48:39 | call to sourceInt(_:) | conversions.swift:48:12:48:40 | call to String.init(_:) [Collection element] | provenance | | | conversions.swift:50:12:50:39 | [...] [Collection element] | conversions.swift:51:12:51:12 | arr | provenance | | | conversions.swift:50:12:50:39 | [...] [Collection element] | conversions.swift:52:12:52:12 | arr [Collection element] | provenance | | | conversions.swift:50:12:50:39 | [...] [Collection element] | conversions.swift:53:20:53:20 | arr [Collection element] | provenance | | @@ -65,13 +67,19 @@ edges | conversions.swift:138:18:138:39 | call to sourceFloat(_:) | conversions.swift:138:12:138:40 | call to UInt8.init(_:) | provenance | | | conversions.swift:139:19:139:40 | call to sourceFloat(_:) | conversions.swift:139:12:139:41 | call to String.init(_:) | provenance | | | conversions.swift:140:12:140:41 | call to String.init(_:) | conversions.swift:140:12:140:43 | .utf8 | provenance | | +| conversions.swift:140:12:140:41 | call to String.init(_:) [Collection element] | conversions.swift:140:12:140:43 | .utf8 | provenance | | | conversions.swift:140:19:140:40 | call to sourceFloat(_:) | conversions.swift:140:12:140:41 | call to String.init(_:) | provenance | | +| conversions.swift:140:19:140:40 | call to sourceFloat(_:) | conversions.swift:140:12:140:41 | call to String.init(_:) [Collection element] | provenance | | | conversions.swift:141:19:141:42 | call to sourceFloat80(_:) | conversions.swift:141:12:141:43 | call to String.init(_:) | provenance | | | conversions.swift:142:12:142:43 | call to String.init(_:) | conversions.swift:142:12:142:45 | .utf8 | provenance | | +| conversions.swift:142:12:142:43 | call to String.init(_:) [Collection element] | conversions.swift:142:12:142:45 | .utf8 | provenance | | | conversions.swift:142:19:142:42 | call to sourceFloat80(_:) | conversions.swift:142:12:142:43 | call to String.init(_:) | provenance | | +| conversions.swift:142:19:142:42 | call to sourceFloat80(_:) | conversions.swift:142:12:142:43 | call to String.init(_:) [Collection element] | provenance | | | conversions.swift:143:19:143:41 | call to sourceDouble(_:) | conversions.swift:143:12:143:42 | call to String.init(_:) | provenance | | | conversions.swift:144:12:144:42 | call to String.init(_:) | conversions.swift:144:12:144:44 | .utf8 | provenance | | +| conversions.swift:144:12:144:42 | call to String.init(_:) [Collection element] | conversions.swift:144:12:144:44 | .utf8 | provenance | | | conversions.swift:144:19:144:41 | call to sourceDouble(_:) | conversions.swift:144:12:144:42 | call to String.init(_:) | provenance | | +| conversions.swift:144:19:144:41 | call to sourceDouble(_:) | conversions.swift:144:12:144:42 | call to String.init(_:) [Collection element] | provenance | | | conversions.swift:146:18:146:39 | call to sourceFloat(_:) | conversions.swift:146:12:146:40 | call to Float.init(_:) | provenance | | | conversions.swift:147:41:147:60 | call to sourceInt(_:) | conversions.swift:147:12:147:79 | call to Float.init(sign:exponent:significand:) | provenance | | | conversions.swift:148:57:148:78 | call to sourceFloat(_:) | conversions.swift:148:12:148:79 | call to Float.init(sign:exponent:significand:) | provenance | | @@ -279,6 +287,7 @@ nodes | conversions.swift:47:12:47:40 | call to String.init(_:) | semmle.label | call to String.init(_:) | | conversions.swift:47:19:47:39 | call to sourceInt(_:) | semmle.label | call to sourceInt(_:) | | conversions.swift:48:12:48:40 | call to String.init(_:) | semmle.label | call to String.init(_:) | +| conversions.swift:48:12:48:40 | call to String.init(_:) [Collection element] | semmle.label | call to String.init(_:) [Collection element] | | conversions.swift:48:12:48:42 | .utf8 | semmle.label | .utf8 | | conversions.swift:48:19:48:39 | call to sourceInt(_:) | semmle.label | call to sourceInt(_:) | | conversions.swift:50:12:50:39 | [...] [Collection element] | semmle.label | [...] [Collection element] | @@ -363,16 +372,19 @@ nodes | conversions.swift:139:12:139:41 | call to String.init(_:) | semmle.label | call to String.init(_:) | | conversions.swift:139:19:139:40 | call to sourceFloat(_:) | semmle.label | call to sourceFloat(_:) | | conversions.swift:140:12:140:41 | call to String.init(_:) | semmle.label | call to String.init(_:) | +| conversions.swift:140:12:140:41 | call to String.init(_:) [Collection element] | semmle.label | call to String.init(_:) [Collection element] | | conversions.swift:140:12:140:43 | .utf8 | semmle.label | .utf8 | | conversions.swift:140:19:140:40 | call to sourceFloat(_:) | semmle.label | call to sourceFloat(_:) | | conversions.swift:141:12:141:43 | call to String.init(_:) | semmle.label | call to String.init(_:) | | conversions.swift:141:19:141:42 | call to sourceFloat80(_:) | semmle.label | call to sourceFloat80(_:) | | conversions.swift:142:12:142:43 | call to String.init(_:) | semmle.label | call to String.init(_:) | +| conversions.swift:142:12:142:43 | call to String.init(_:) [Collection element] | semmle.label | call to String.init(_:) [Collection element] | | conversions.swift:142:12:142:45 | .utf8 | semmle.label | .utf8 | | conversions.swift:142:19:142:42 | call to sourceFloat80(_:) | semmle.label | call to sourceFloat80(_:) | | conversions.swift:143:12:143:42 | call to String.init(_:) | semmle.label | call to String.init(_:) | | conversions.swift:143:19:143:41 | call to sourceDouble(_:) | semmle.label | call to sourceDouble(_:) | | conversions.swift:144:12:144:42 | call to String.init(_:) | semmle.label | call to String.init(_:) | +| conversions.swift:144:12:144:42 | call to String.init(_:) [Collection element] | semmle.label | call to String.init(_:) [Collection element] | | conversions.swift:144:12:144:44 | .utf8 | semmle.label | .utf8 | | conversions.swift:144:19:144:41 | call to sourceDouble(_:) | semmle.label | call to sourceDouble(_:) | | conversions.swift:146:12:146:40 | call to Float.init(_:) | semmle.label | call to Float.init(_:) | diff --git a/swift/ql/test/library-tests/dataflow/taint/libraries/custom.swift b/swift/ql/test/library-tests/dataflow/taint/libraries/custom.swift index de2f6d5fadfa..1b6402f6a8c7 100644 --- a/swift/ql/test/library-tests/dataflow/taint/libraries/custom.swift +++ b/swift/ql/test/library-tests/dataflow/taint/libraries/custom.swift @@ -115,6 +115,6 @@ func testCustom() { sink(arg: mc7) sink(arg: mc7[0]) mc7.append(contentsOf: taintedArray) - sink(arg: mc7) // $ MISSING: tainted=data10 - sink(arg: mc7[0]) // $ MISSING: tainted=data10 + sink(arg: mc7) // $ tainted=data10 + sink(arg: mc7[0]) // $ tainted=data10 } diff --git a/swift/ql/test/library-tests/dataflow/taint/libraries/files.swift b/swift/ql/test/library-tests/dataflow/taint/libraries/files.swift index 7a65a2d10f69..811107fc3795 100644 --- a/swift/ql/test/library-tests/dataflow/taint/libraries/files.swift +++ b/swift/ql/test/library-tests/dataflow/taint/libraries/files.swift @@ -125,7 +125,7 @@ func test_files(e1: Encoder) { sink(filePath: FilePath(cString: sourceCString())) // $ tainted=125 sink(filePath: FilePath(root: FilePath.Root("/"), [FilePath.Component("my")!, FilePath.Component("path")!])) sink(filePath: FilePath(root: FilePath.Root(sourceString()), [FilePath.Component("my")!, FilePath.Component("path")!])) // $ tainted=127 - sink(filePath: FilePath(root: FilePath.Root("/"), [FilePath.Component("my")!, FilePath.Component(sourceString())!])) // $ MISSING: tainted= + sink(filePath: FilePath(root: FilePath.Root("/"), [FilePath.Component("my")!, FilePath.Component(sourceString())!])) // $ tainted=128 // --- FilePath methods --- diff --git a/swift/ql/test/library-tests/dataflow/taint/libraries/set.swift b/swift/ql/test/library-tests/dataflow/taint/libraries/set.swift index b7ca5b86cca4..76b41ff8b93a 100644 --- a/swift/ql/test/library-tests/dataflow/taint/libraries/set.swift +++ b/swift/ql/test/library-tests/dataflow/taint/libraries/set.swift @@ -28,7 +28,7 @@ func testSet(ix: Int) { sink(arg: taintedSet.max()!) // $ tainted=t1 sink(arg: taintedSet.firstIndex(of: source("t2"))!) sink(arg: taintedSet[taintedSet.firstIndex(of: source("t3"))!]) // $ tainted=t1 - sink(arg: taintedSet.first!) // $ MISSING: tainted=t1 + sink(arg: taintedSet.first!) // $ tainted=t1 for elem in taintedSet { sink(arg: elem) // $ tainted=t1 } @@ -100,7 +100,7 @@ func testSet(ix: Int) { sink(arg: taintedSet.sorted().randomElement()!) // $ tainted=t1 sink(arg: taintedSet.shuffled().randomElement()!) // $ tainted=t1 - sink(arg: taintedSet.lazy[taintedSet.firstIndex(of: source("t11"))!]) // $ MISSING: tainted=t1 + sink(arg: taintedSet.lazy[taintedSet.firstIndex(of: source("t11"))!]) // $ tainted=t1 var it = taintedSet.makeIterator() sink(arg: it.next()!) // $ tainted=t1 diff --git a/swift/ql/test/library-tests/dataflow/taint/libraries/url.swift b/swift/ql/test/library-tests/dataflow/taint/libraries/url.swift index b6675f42c299..ea0cf867ff9d 100644 --- a/swift/ql/test/library-tests/dataflow/taint/libraries/url.swift +++ b/swift/ql/test/library-tests/dataflow/taint/libraries/url.swift @@ -292,7 +292,7 @@ func taintThroughURL() { sink(arg: URL(fileURLWithFileSystemRepresentation: 0 as! UnsafePointer, isDirectory: false, relativeTo: urlTainted)) // $ tainted=210 let _ = tainted.withCString({ ptrTainted in - sink(arg: URL(fileURLWithFileSystemRepresentation: ptrTainted, isDirectory: false, relativeTo: nil)) // $ MISSING: tainted=210 + sink(arg: URL(fileURLWithFileSystemRepresentation: ptrTainted, isDirectory: false, relativeTo: nil)) // $ tainted=210 }) sink(arg: URL(fileReferenceLiteralResourceName: tainted)) // $ tainted=210 @@ -339,12 +339,12 @@ func taintThroughURL() { sink(arg: urlTainted.appending(component: clean)) // $ tainted=210 sink(arg: urlClean.appending(component: tainted)) // $ tainted=210 sink(arg: urlTainted.appending(components: clean)) // $ tainted=210 - sink(arg: urlClean.appending(components: tainted)) // $ MISSING: tainted=210 - sink(arg: urlClean.appending(components: clean, tainted)) // $ MISSING: tainted=210 + sink(arg: urlClean.appending(components: tainted)) // $ tainted=210 + sink(arg: urlClean.appending(components: clean, tainted)) // $ tainted=210 sink(arg: urlTainted.appending(path: clean)) // $ tainted=210 sink(arg: urlClean.appending(path: tainted)) // $ tainted=210 sink(arg: urlTainted.appending(queryItems: [])) // $ tainted=210 - sink(arg: urlClean.appending(queryItems: [source() as! URLQueryItem])) // $ MISSING: tainted=210 + sink(arg: urlClean.appending(queryItems: [source() as! URLQueryItem])) // $ tainted=347 sink(arg: URL(filePath: tainted)) // $ tainted=210 sink(arg: URL(filePath: tainted, relativeTo: nil)) // $ tainted=210 @@ -403,11 +403,11 @@ func taintThroughURL() { var url7 = URL(string: clean)! url7.append(components: tainted) - sink(arg: url7) // $ MISSING: tainted=210 + sink(arg: url7) // $ tainted=210 var url8 = URL(string: clean)! url8.append(components: clean, tainted) - sink(arg: url8) // $ MISSING: tainted=210 + sink(arg: url8) // $ tainted=210 var url9 = URL(string: clean)! url9.append(path: tainted) @@ -415,7 +415,7 @@ func taintThroughURL() { var url10 = URL(string: clean)! url10.append(queryItems: [source() as! URLQueryItem]) - sink(arg: url10) // $ MISSING: tainted=210 + sink(arg: url10) // $ tainted=417 sink(data: try! urlTainted.bookmarkData()) // $ tainted=210 sink(data: try! URL.bookmarkData(withContentsOf: urlTainted)) // $ tainted=210