Skip to content

Commit 759d986

Browse files
author
Max Schaefer
authored
Merge pull request #117 from esben-semmle/js/push-sort-taint-steps
JS: support `push` and `sort` taint steps for arrays
2 parents 20bff70 + c1e6280 commit 759d986

File tree

4 files changed

+28
-1
lines changed

4 files changed

+28
-1
lines changed

change-notes/1.18/analysis-javascript.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
* Modelling of re-export declarations has been improved. This may result in fewer false-positive results for a variety of queries.
1212

13-
* Modelling of taint flow through the array operations `map` and `join` has been improved. This may give additional results for the security queries.
13+
* Modelling of taint flow through array operations has been improved. This may give additional results for the security queries.
1414

1515
* The taint tracking library recognizes more ways in which taint propagates. In particular, some flow through string formatters is now recognized. This may give additional results for the security queries.
1616

javascript/ql/src/semmle/javascript/dataflow/TaintTracking.qll

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,9 @@ module TaintTracking {
214214
m.getMethodName() = "map" and
215215
m.getArgument(0) = f and // Require the argument to be a closure to avoid spurious call/return flow
216216
pred = f.getAReturnedExpr().flow())
217+
or
218+
// `array.push(e)`: if `e` is tainted, then so is `array`
219+
succ.(DataFlow::SourceNode).getAMethodCall("push").getAnArgument() = pred
217220
)
218221
or
219222
// reading from a tainted object yields a tainted result
@@ -508,6 +511,19 @@ module TaintTracking {
508511
}
509512
}
510513

514+
/**
515+
* A taint propagating data flow edge arising from sorting.
516+
*/
517+
private class SortTaintStep extends AdditionalTaintStep, DataFlow::MethodCallNode {
518+
SortTaintStep() {
519+
getMethodName() = "sort"
520+
}
521+
522+
override predicate step(DataFlow::Node pred, DataFlow::Node succ) {
523+
pred = getReceiver() and succ = this
524+
}
525+
}
526+
511527
/**
512528
* A conditional checking a tainted string against a regular expression, which is
513529
* considered to be a sanitizer for all configurations.
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,5 @@
11
| tst.js:2:13:2:20 | source() | tst.js:4:10:4:10 | x |
22
| tst.js:2:13:2:20 | source() | tst.js:5:10:5:22 | "/" + x + "!" |
3+
| tst.js:2:13:2:20 | source() | tst.js:14:10:14:17 | x.sort() |
4+
| tst.js:2:13:2:20 | source() | tst.js:17:10:17:10 | a |
5+
| tst.js:2:13:2:20 | source() | tst.js:19:10:19:10 | a |

javascript/ql/test/library-tests/TaintTracking/tst.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,12 @@ function test() {
1010
sink(x === 1); // OK
1111
sink(undefined == x); // OK
1212
sink(x === x); // OK
13+
14+
sink(x.sort()); // NOT OK
15+
16+
var a = [];
17+
sink(a); // NOT OK (flow-insensitive treatment of `a`)
18+
a.push(x);
19+
sink(a); // NOT OK
20+
1321
}

0 commit comments

Comments
 (0)