Skip to content

Commit 738123d

Browse files
asger-semmleasgerf
authored andcommitted
JS: More sanitizers
1 parent f7543ae commit 738123d

File tree

1 file changed

+41
-6
lines changed

1 file changed

+41
-6
lines changed

javascript/ql/src/Security/CWE-400/PrototypePollutionUtility.ql

Lines changed: 41 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -261,22 +261,24 @@ class PropNameTracking extends DataFlow::Configuration {
261261
}
262262

263263
override predicate isBarrierGuard(DataFlow::BarrierGuardNode node) {
264-
node instanceof EqualityGuard or
264+
node instanceof BlacklistEqualityGuard or
265+
node instanceof WhitelistEqualityGuard or
265266
node instanceof HasOwnPropertyGuard or
266267
node instanceof InstanceOfGuard or
267268
node instanceof TypeofGuard or
268-
node instanceof ArrayInclusionGuard
269+
node instanceof BlacklistInclusionGuard or
270+
node instanceof WhitelistInclusionGuard
269271
}
270272
}
271273

272274
/**
273275
* Sanitizer guard of form `x === "__proto__"` or `x === "constructor"`.
274276
*/
275-
class EqualityGuard extends DataFlow::LabeledBarrierGuardNode, ValueNode {
277+
class BlacklistEqualityGuard extends DataFlow::LabeledBarrierGuardNode, ValueNode {
276278
override EqualityTest astNode;
277279
string propName;
278280

279-
EqualityGuard() {
281+
BlacklistEqualityGuard() {
280282
astNode.getAnOperand().getStringValue() = propName and
281283
propName = unsafePropName()
282284
}
@@ -288,6 +290,24 @@ class EqualityGuard extends DataFlow::LabeledBarrierGuardNode, ValueNode {
288290
}
289291
}
290292

293+
/**
294+
* An equality test with something other than `__proto__` or `constructor`.
295+
*/
296+
class WhitelistEqualityGuard extends DataFlow::LabeledBarrierGuardNode, ValueNode {
297+
override EqualityTest astNode;
298+
299+
WhitelistEqualityGuard() {
300+
not astNode.getAnOperand().getStringValue() = unsafePropName() and
301+
astNode.getAnOperand() instanceof Literal
302+
}
303+
304+
override predicate blocks(boolean outcome, Expr e, FlowLabel label) {
305+
e = astNode.getAnOperand() and
306+
outcome = astNode.getPolarity() and
307+
label instanceof UnsafePropLabel
308+
}
309+
}
310+
291311
/**
292312
* Sanitizer guard for calls to `Object.prototype.hasOwnProperty`.
293313
*
@@ -371,10 +391,10 @@ class TypeofGuard extends DataFlow::LabeledBarrierGuardNode, DataFlow::ValueNode
371391
/**
372392
* A check of form `["__proto__"].includes(x)` or similar.
373393
*/
374-
class ArrayInclusionGuard extends DataFlow::LabeledBarrierGuardNode, InclusionTest {
394+
class BlacklistInclusionGuard extends DataFlow::LabeledBarrierGuardNode, InclusionTest {
375395
UnsafePropLabel label;
376396

377-
ArrayInclusionGuard() {
397+
BlacklistInclusionGuard() {
378398
exists(DataFlow::ArrayCreationNode array |
379399
array.getAnElement().getStringValue() = label and
380400
array.flowsTo(getContainerNode())
@@ -388,6 +408,21 @@ class ArrayInclusionGuard extends DataFlow::LabeledBarrierGuardNode, InclusionTe
388408
}
389409
}
390410

411+
/**
412+
* A check of form `xs.includes(x)` or similar, which sanitizes `x` in the true case.
413+
*/
414+
class WhitelistInclusionGuard extends DataFlow::LabeledBarrierGuardNode {
415+
WhitelistInclusionGuard() {
416+
this instanceof TaintTracking::PositiveIndexOfSanitizer or
417+
this instanceof TaintTracking::InclusionSanitizer
418+
}
419+
420+
override predicate blocks(boolean outcome, Expr e, DataFlow::FlowLabel lbl) {
421+
this.(TaintTracking::AdditionalSanitizerGuardNode).sanitizes(outcome, e) and
422+
lbl instanceof UnsafePropLabel
423+
}
424+
}
425+
391426
/**
392427
* Gets a meaningful name for `node` if possible.
393428
*/

0 commit comments

Comments
 (0)