diff --git a/change-notes/1.19/analysis-javascript.md b/change-notes/1.19/analysis-javascript.md index 4d23f695d9e0..8ddbf14b0873 100644 --- a/change-notes/1.19/analysis-javascript.md +++ b/change-notes/1.19/analysis-javascript.md @@ -4,6 +4,8 @@ * Modelling of taint flow through array operations has been improved. This may give additional results for the security queries. +* The taint tracking library now recognizes additional sanitization patterns. This may give fewer false-positive results for the security queries. + * Support for popular libraries has been improved. Consequently, queries may produce more results on code bases that use the following features: - file system access, for example through [fs-extra](https://github.com/jprichardson/node-fs-extra) or [globby](https://www.npmjs.com/package/globby) diff --git a/javascript/ql/src/semmle/javascript/dataflow/TaintTracking.qll b/javascript/ql/src/semmle/javascript/dataflow/TaintTracking.qll index 55f8ec8b9e7e..05dfb29c4ad1 100644 --- a/javascript/ql/src/semmle/javascript/dataflow/TaintTracking.qll +++ b/javascript/ql/src/semmle/javascript/dataflow/TaintTracking.qll @@ -625,6 +625,26 @@ module TaintTracking { } + /** + * A check of the form `if((x))`, which sanitizes `x` in its "then" branch. + * + * `` is a call with callee name 'safe', 'whitelist', 'allow', or similar. + * + * This sanitizer is not enabled by default. + */ + class AdHocWhitelistCheckSanitizer extends SanitizerGuardNode, DataFlow::CallNode { + AdHocWhitelistCheckSanitizer() { + getCalleeName().regexpMatch("(?i).*((? -1 | ExampleConfiguration | true | tst.js:220:19:220:19 | v | | tst.js:226:9:226:26 | -1 >= o.indexOf(v) | ExampleConfiguration | false | tst.js:226:25:226:25 | v | +| tst.js:236:9:236:24 | isWhitelisted(v) | ExampleConfiguration | true | tst.js:236:23:236:23 | v | +| tst.js:240:9:240:28 | config.allowValue(v) | ExampleConfiguration | true | tst.js:240:27:240:27 | v | diff --git a/javascript/ql/test/library-tests/TaintBarriers/TaintedSink.expected b/javascript/ql/test/library-tests/TaintBarriers/TaintedSink.expected index 1831db03e3d0..81935683df3e 100644 --- a/javascript/ql/test/library-tests/TaintBarriers/TaintedSink.expected +++ b/javascript/ql/test/library-tests/TaintBarriers/TaintedSink.expected @@ -34,3 +34,5 @@ | tst.js:215:14:215:14 | v | tst.js:199:13:199:20 | SOURCE() | | tst.js:223:14:223:14 | v | tst.js:199:13:199:20 | SOURCE() | | tst.js:227:14:227:14 | v | tst.js:199:13:199:20 | SOURCE() | +| tst.js:239:14:239:14 | v | tst.js:235:13:235:20 | SOURCE() | +| tst.js:243:14:243:14 | v | tst.js:235:13:235:20 | SOURCE() | diff --git a/javascript/ql/test/library-tests/TaintBarriers/isBarrier.expected b/javascript/ql/test/library-tests/TaintBarriers/isBarrier.expected index 530c48093f79..315e118a0837 100644 --- a/javascript/ql/test/library-tests/TaintBarriers/isBarrier.expected +++ b/javascript/ql/test/library-tests/TaintBarriers/isBarrier.expected @@ -29,3 +29,5 @@ | tst.js:217:14:217:14 | v | ExampleConfiguration | | tst.js:221:14:221:14 | v | ExampleConfiguration | | tst.js:229:14:229:14 | v | ExampleConfiguration | +| tst.js:237:14:237:14 | v | ExampleConfiguration | +| tst.js:241:14:241:14 | v | ExampleConfiguration | diff --git a/javascript/ql/test/library-tests/TaintBarriers/tst.js b/javascript/ql/test/library-tests/TaintBarriers/tst.js index c0d7179a7a08..ea0cc0951759 100644 --- a/javascript/ql/test/library-tests/TaintBarriers/tst.js +++ b/javascript/ql/test/library-tests/TaintBarriers/tst.js @@ -230,3 +230,16 @@ function RelationalIndexOfCheckSanitizer () { } } + +function adhocWhitelisting() { + var v = SOURCE(); + if (isWhitelisted(v)) + SINK(v); + else + SINK(v); + if (config.allowValue(v)) + SINK(v); + else + SINK(v); + +}