Skip to content

Commit e94b0f5

Browse files
committed
recognize inclusion based sanitizers for js/prototype-polluting-assignment
1 parent 2a808b2 commit e94b0f5

File tree

3 files changed

+27
-1
lines changed

3 files changed

+27
-1
lines changed

javascript/ql/lib/semmle/javascript/security/dataflow/PrototypePollutingAssignmentQuery.qll

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,8 @@ class Configuration extends TaintTracking::Configuration {
8484
guard instanceof InstanceofCheck or
8585
guard instanceof IsArrayCheck or
8686
guard instanceof TypeofCheck or
87-
guard instanceof EqualityCheck
87+
guard instanceof EqualityCheck or
88+
guard instanceof IncludesCheck
8889
}
8990
}
9091

@@ -204,3 +205,15 @@ private class EqualityCheck extends TaintTracking::SanitizerGuardNode, DataFlow:
204205
outcome = astNode.getPolarity().booleanNot()
205206
}
206207
}
208+
209+
/**
210+
* Sanitizer guard of the form `x.includes("__proto__")`.
211+
*/
212+
private class IncludesCheck extends TaintTracking::LabeledSanitizerGuardNode, InclusionTest {
213+
IncludesCheck() { this.getContainedNode().mayHaveStringValue("__proto__") }
214+
215+
override predicate sanitizes(boolean outcome, Expr e) {
216+
e = getContainerNode().asExpr() and
217+
outcome = getPolarity().booleanNot()
218+
}
219+
}

javascript/ql/test/query-tests/Security/CWE-915/PrototypePollutingAssignment/PrototypePollutingAssignment.expected

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,9 @@ nodes
6767
| tst.js:82:5:82:22 | object["" + taint] |
6868
| tst.js:82:12:82:21 | "" + taint |
6969
| tst.js:82:17:82:21 | taint |
70+
| tst.js:87:9:87:21 | object[taint] |
71+
| tst.js:87:9:87:21 | object[taint] |
72+
| tst.js:87:16:87:20 | taint |
7073
edges
7174
| lib.js:1:38:1:40 | obj | lib.js:6:7:6:9 | obj |
7275
| lib.js:1:38:1:40 | obj | lib.js:6:7:6:9 | obj |
@@ -126,6 +129,7 @@ edges
126129
| tst.js:33:23:33:25 | obj | tst.js:48:9:48:11 | obj |
127130
| tst.js:77:9:77:38 | taint | tst.js:80:12:80:16 | taint |
128131
| tst.js:77:9:77:38 | taint | tst.js:82:17:82:21 | taint |
132+
| tst.js:77:9:77:38 | taint | tst.js:87:16:87:20 | taint |
129133
| tst.js:77:17:77:38 | String( ... y.data) | tst.js:77:9:77:38 | taint |
130134
| tst.js:77:24:77:37 | req.query.data | tst.js:77:17:77:38 | String( ... y.data) |
131135
| tst.js:77:24:77:37 | req.query.data | tst.js:77:17:77:38 | String( ... y.data) |
@@ -134,6 +138,8 @@ edges
134138
| tst.js:82:12:82:21 | "" + taint | tst.js:82:5:82:22 | object["" + taint] |
135139
| tst.js:82:12:82:21 | "" + taint | tst.js:82:5:82:22 | object["" + taint] |
136140
| tst.js:82:17:82:21 | taint | tst.js:82:12:82:21 | "" + taint |
141+
| tst.js:87:16:87:20 | taint | tst.js:87:9:87:21 | object[taint] |
142+
| tst.js:87:16:87:20 | taint | tst.js:87:9:87:21 | object[taint] |
137143
#select
138144
| lib.js:6:7:6:9 | obj | lib.js:1:43:1:46 | path | lib.js:6:7:6:9 | obj | This assignment may alter Object.prototype if a malicious '__proto__' string is injected from $@. | lib.js:1:43:1:46 | path | here |
139145
| lib.js:15:3:15:14 | obj[path[0]] | lib.js:14:38:14:41 | path | lib.js:15:3:15:14 | obj[path[0]] | This assignment may alter Object.prototype if a malicious '__proto__' string is injected from $@. | lib.js:14:38:14:41 | path | here |
@@ -147,3 +153,4 @@ edges
147153
| tst.js:48:9:48:11 | obj | tst.js:5:24:5:37 | req.query.data | tst.js:48:9:48:11 | obj | This assignment may alter Object.prototype if a malicious '__proto__' string is injected from $@. | tst.js:5:24:5:37 | req.query.data | here |
148154
| tst.js:80:5:80:17 | object[taint] | tst.js:77:24:77:37 | req.query.data | tst.js:80:5:80:17 | object[taint] | This assignment may alter Object.prototype if a malicious '__proto__' string is injected from $@. | tst.js:77:24:77:37 | req.query.data | here |
149155
| tst.js:82:5:82:22 | object["" + taint] | tst.js:77:24:77:37 | req.query.data | tst.js:82:5:82:22 | object["" + taint] | This assignment may alter Object.prototype if a malicious '__proto__' string is injected from $@. | tst.js:77:24:77:37 | req.query.data | here |
156+
| tst.js:87:9:87:21 | object[taint] | tst.js:77:24:77:37 | req.query.data | tst.js:87:9:87:21 | object[taint] | This assignment may alter Object.prototype if a malicious '__proto__' string is injected from $@. | tst.js:77:24:77:37 | req.query.data | here |

javascript/ql/test/query-tests/Security/CWE-915/PrototypePollutingAssignment/tst.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,5 +80,11 @@ app.get('/', (req, res) => {
8080
object[taint][taint] = taint; // NOT OK
8181

8282
object["" + taint]["" + taint] = taint; // NOT OK
83+
84+
if (!taint.includes("__proto__")) {
85+
object[taint][taint] = taint; // OK
86+
} else {
87+
object[taint][taint] = taint; // NOT OK
88+
}
8389
});
8490

0 commit comments

Comments
 (0)