Skip to content

Commit a93939b

Browse files
authored
Merge pull request #230 from esben-semmle/js/ad-hoc-whitelisting
Approved by xiemaisi
2 parents 57f3ac8 + 097a281 commit a93939b

File tree

8 files changed

+51
-0
lines changed

8 files changed

+51
-0
lines changed

change-notes/1.19/analysis-javascript.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44

55
* Modelling of taint flow through array operations has been improved. This may give additional results for the security queries.
66

7+
* The taint tracking library now recognizes additional sanitization patterns. This may give fewer false-positive results for the security queries.
8+
79
* Support for popular libraries has been improved. Consequently, queries may produce more results on code bases that use the following features:
810
- file system access, for example through [fs-extra](https://github.com/jprichardson/node-fs-extra) or [globby](https://www.npmjs.com/package/globby)
911

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

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -614,6 +614,26 @@ module TaintTracking {
614614

615615
}
616616

617+
/**
618+
* A check of the form `if(<isWhitelisted>(x))`, which sanitizes `x` in its "then" branch.
619+
*
620+
* `<isWhitelisted>` is a call with callee name 'safe', 'whitelist', 'allow', or similar.
621+
*
622+
* This sanitizer is not enabled by default.
623+
*/
624+
class AdHocWhitelistCheckSanitizer extends SanitizerGuardNode, DataFlow::CallNode {
625+
AdHocWhitelistCheckSanitizer() {
626+
getCalleeName().regexpMatch("(?i).*((?<!un)safe|whitelist|allow|(?<!un)auth(?!or\\b)).*") and
627+
getNumArgument() = 1
628+
}
629+
630+
override predicate sanitizes(boolean outcome, Expr e) {
631+
outcome = true and
632+
e = getArgument(0).asExpr()
633+
}
634+
635+
}
636+
617637
/** A check of the form `if(x in o)`, which sanitizes `x` in its "then" branch. */
618638
class InSanitizer extends AdditionalSanitizerGuardNode, DataFlow::ValueNode {
619639

javascript/ql/src/semmle/javascript/security/dataflow/CorsMisconfigurationForCredentials.qll

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,11 @@ module CorsMisconfigurationForCredentials {
4949
super.isSanitizer(node) or
5050
node instanceof Sanitizer
5151
}
52+
53+
override predicate isSanitizerGuard(TaintTracking::SanitizerGuardNode guard) {
54+
guard instanceof TaintTracking::AdHocWhitelistCheckSanitizer
55+
}
56+
5257
}
5358

5459
/** A source of remote user input, considered as a flow source for CORS misconfiguration. */

javascript/ql/test/library-tests/TaintBarriers/ExampleConfiguration.qll

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,4 +23,9 @@ class ExampleConfiguration extends TaintTracking::Configuration {
2323
)
2424
}
2525

26+
override predicate isSanitizerGuard(TaintTracking::SanitizerGuardNode guard) {
27+
// add additional generic sanitizers
28+
guard instanceof TaintTracking::AdHocWhitelistCheckSanitizer
29+
}
30+
2631
}

javascript/ql/test/library-tests/TaintBarriers/SanitizingGuard.expected

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,3 +36,5 @@
3636
| tst.js:214:9:214:24 | o.indexOf(v) < 0 | ExampleConfiguration | false | tst.js:214:19:214:19 | v |
3737
| tst.js:220:9:220:25 | o.indexOf(v) > -1 | ExampleConfiguration | true | tst.js:220:19:220:19 | v |
3838
| tst.js:226:9:226:26 | -1 >= o.indexOf(v) | ExampleConfiguration | false | tst.js:226:25:226:25 | v |
39+
| tst.js:236:9:236:24 | isWhitelisted(v) | ExampleConfiguration | true | tst.js:236:23:236:23 | v |
40+
| tst.js:240:9:240:28 | config.allowValue(v) | ExampleConfiguration | true | tst.js:240:27:240:27 | v |

javascript/ql/test/library-tests/TaintBarriers/TaintedSink.expected

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,3 +34,5 @@
3434
| tst.js:215:14:215:14 | v | tst.js:199:13:199:20 | SOURCE() |
3535
| tst.js:223:14:223:14 | v | tst.js:199:13:199:20 | SOURCE() |
3636
| tst.js:227:14:227:14 | v | tst.js:199:13:199:20 | SOURCE() |
37+
| tst.js:239:14:239:14 | v | tst.js:235:13:235:20 | SOURCE() |
38+
| tst.js:243:14:243:14 | v | tst.js:235:13:235:20 | SOURCE() |

javascript/ql/test/library-tests/TaintBarriers/isBarrier.expected

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,3 +29,5 @@
2929
| tst.js:217:14:217:14 | v | ExampleConfiguration |
3030
| tst.js:221:14:221:14 | v | ExampleConfiguration |
3131
| tst.js:229:14:229:14 | v | ExampleConfiguration |
32+
| tst.js:237:14:237:14 | v | ExampleConfiguration |
33+
| tst.js:241:14:241:14 | v | ExampleConfiguration |

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

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,3 +230,16 @@ function RelationalIndexOfCheckSanitizer () {
230230
}
231231

232232
}
233+
234+
function adhocWhitelisting() {
235+
var v = SOURCE();
236+
if (isWhitelisted(v))
237+
SINK(v);
238+
else
239+
SINK(v);
240+
if (config.allowValue(v))
241+
SINK(v);
242+
else
243+
SINK(v);
244+
245+
}

0 commit comments

Comments
 (0)