Skip to content

Commit bffb127

Browse files
committed
add test and change-note to prototype-polution
1 parent 38db731 commit bffb127

File tree

4 files changed

+77
-1
lines changed

4 files changed

+77
-1
lines changed

change-notes/1.25/analysis-javascript.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
| Client-side URL redirect (`js/client-side-unvalidated-url-redirection`) | Less results | This query now recognizes additional safe patterns of doing URL redirects. |
2424
| Client-side cross-site scripting (`js/xss`) | Less results | This query now recognizes more safe strings based on URLs. |
2525
| Incomplete URL scheme check (`js/incomplete-url-scheme-check`) | More results | This query now recognizes more url scheme checks. |
26+
| Prototype pollution in utility function (`js/prototype-pollution-utility`) | More results | This query now recognizes more utility functions vulnerable to prototype polution. |
2627

2728
## Changes to libraries
2829

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ import semmle.javascript.DynamicPropertyAccess
2424
class SplitCall extends StringSplitCall {
2525
SplitCall() {
2626
getSeparator() = "." and
27-
getBaseString() instanceof ParameterNode
27+
getBaseString().getALocalSource() instanceof ParameterNode
2828
}
2929
}
3030

javascript/ql/test/query-tests/Security/CWE-400/PrototypePollutionUtility.expected

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,37 @@ nodes
8080
| PrototypePollutionUtility/path-assignment.js:61:12:61:18 | keys[i] |
8181
| PrototypePollutionUtility/path-assignment.js:61:12:61:18 | keys[i] |
8282
| PrototypePollutionUtility/path-assignment.js:61:12:61:18 | keys[i] |
83+
| PrototypePollutionUtility/path-assignment.js:68:13:68:25 | key |
84+
| PrototypePollutionUtility/path-assignment.js:68:13:68:25 | key |
85+
| PrototypePollutionUtility/path-assignment.js:68:19:68:25 | keys[i] |
86+
| PrototypePollutionUtility/path-assignment.js:68:19:68:25 | keys[i] |
87+
| PrototypePollutionUtility/path-assignment.js:68:19:68:25 | keys[i] |
88+
| PrototypePollutionUtility/path-assignment.js:69:9:69:48 | target |
89+
| PrototypePollutionUtility/path-assignment.js:69:9:69:48 | target |
90+
| PrototypePollutionUtility/path-assignment.js:69:18:69:23 | target |
91+
| PrototypePollutionUtility/path-assignment.js:69:18:69:23 | target |
92+
| PrototypePollutionUtility/path-assignment.js:69:18:69:23 | target |
93+
| PrototypePollutionUtility/path-assignment.js:69:18:69:48 | target[ ... ] \|\| {} |
94+
| PrototypePollutionUtility/path-assignment.js:69:18:69:48 | target[ ... ] \|\| {} |
95+
| PrototypePollutionUtility/path-assignment.js:69:25:69:27 | key |
96+
| PrototypePollutionUtility/path-assignment.js:69:25:69:27 | key |
97+
| PrototypePollutionUtility/path-assignment.js:69:25:69:27 | key |
98+
| PrototypePollutionUtility/path-assignment.js:69:32:69:37 | target |
99+
| PrototypePollutionUtility/path-assignment.js:69:32:69:37 | target |
100+
| PrototypePollutionUtility/path-assignment.js:69:32:69:42 | target[key] |
101+
| PrototypePollutionUtility/path-assignment.js:69:32:69:42 | target[key] |
102+
| PrototypePollutionUtility/path-assignment.js:69:32:69:48 | target[key] \|\| {} |
103+
| PrototypePollutionUtility/path-assignment.js:69:32:69:48 | target[key] \|\| {} |
104+
| PrototypePollutionUtility/path-assignment.js:69:32:69:48 | target[key] \|\| {} |
105+
| PrototypePollutionUtility/path-assignment.js:69:39:69:41 | key |
106+
| PrototypePollutionUtility/path-assignment.js:69:39:69:41 | key |
107+
| PrototypePollutionUtility/path-assignment.js:71:5:71:10 | target |
108+
| PrototypePollutionUtility/path-assignment.js:71:5:71:10 | target |
109+
| PrototypePollutionUtility/path-assignment.js:71:5:71:10 | target |
110+
| PrototypePollutionUtility/path-assignment.js:71:12:71:18 | keys[i] |
111+
| PrototypePollutionUtility/path-assignment.js:71:12:71:18 | keys[i] |
112+
| PrototypePollutionUtility/path-assignment.js:71:12:71:18 | keys[i] |
113+
| PrototypePollutionUtility/path-assignment.js:71:12:71:18 | keys[i] |
83114
| PrototypePollutionUtility/tests.js:3:25:3:27 | dst |
84115
| PrototypePollutionUtility/tests.js:3:25:3:27 | dst |
85116
| PrototypePollutionUtility/tests.js:3:30:3:32 | src |
@@ -1378,6 +1409,39 @@ edges
13781409
| PrototypePollutionUtility/path-assignment.js:59:39:59:41 | key | PrototypePollutionUtility/path-assignment.js:59:32:59:42 | target[key] |
13791410
| PrototypePollutionUtility/path-assignment.js:59:39:59:41 | key | PrototypePollutionUtility/path-assignment.js:59:32:59:42 | target[key] |
13801411
| PrototypePollutionUtility/path-assignment.js:61:12:61:18 | keys[i] | PrototypePollutionUtility/path-assignment.js:61:12:61:18 | keys[i] |
1412+
| PrototypePollutionUtility/path-assignment.js:68:13:68:25 | key | PrototypePollutionUtility/path-assignment.js:69:25:69:27 | key |
1413+
| PrototypePollutionUtility/path-assignment.js:68:13:68:25 | key | PrototypePollutionUtility/path-assignment.js:69:25:69:27 | key |
1414+
| PrototypePollutionUtility/path-assignment.js:68:13:68:25 | key | PrototypePollutionUtility/path-assignment.js:69:25:69:27 | key |
1415+
| PrototypePollutionUtility/path-assignment.js:68:13:68:25 | key | PrototypePollutionUtility/path-assignment.js:69:25:69:27 | key |
1416+
| PrototypePollutionUtility/path-assignment.js:68:13:68:25 | key | PrototypePollutionUtility/path-assignment.js:69:39:69:41 | key |
1417+
| PrototypePollutionUtility/path-assignment.js:68:13:68:25 | key | PrototypePollutionUtility/path-assignment.js:69:39:69:41 | key |
1418+
| PrototypePollutionUtility/path-assignment.js:68:19:68:25 | keys[i] | PrototypePollutionUtility/path-assignment.js:68:13:68:25 | key |
1419+
| PrototypePollutionUtility/path-assignment.js:68:19:68:25 | keys[i] | PrototypePollutionUtility/path-assignment.js:68:13:68:25 | key |
1420+
| PrototypePollutionUtility/path-assignment.js:68:19:68:25 | keys[i] | PrototypePollutionUtility/path-assignment.js:68:13:68:25 | key |
1421+
| PrototypePollutionUtility/path-assignment.js:68:19:68:25 | keys[i] | PrototypePollutionUtility/path-assignment.js:68:13:68:25 | key |
1422+
| PrototypePollutionUtility/path-assignment.js:69:9:69:48 | target | PrototypePollutionUtility/path-assignment.js:69:18:69:23 | target |
1423+
| PrototypePollutionUtility/path-assignment.js:69:9:69:48 | target | PrototypePollutionUtility/path-assignment.js:69:18:69:23 | target |
1424+
| PrototypePollutionUtility/path-assignment.js:69:9:69:48 | target | PrototypePollutionUtility/path-assignment.js:69:18:69:23 | target |
1425+
| PrototypePollutionUtility/path-assignment.js:69:9:69:48 | target | PrototypePollutionUtility/path-assignment.js:69:18:69:23 | target |
1426+
| PrototypePollutionUtility/path-assignment.js:69:9:69:48 | target | PrototypePollutionUtility/path-assignment.js:69:32:69:37 | target |
1427+
| PrototypePollutionUtility/path-assignment.js:69:9:69:48 | target | PrototypePollutionUtility/path-assignment.js:69:32:69:37 | target |
1428+
| PrototypePollutionUtility/path-assignment.js:69:9:69:48 | target | PrototypePollutionUtility/path-assignment.js:71:5:71:10 | target |
1429+
| PrototypePollutionUtility/path-assignment.js:69:9:69:48 | target | PrototypePollutionUtility/path-assignment.js:71:5:71:10 | target |
1430+
| PrototypePollutionUtility/path-assignment.js:69:9:69:48 | target | PrototypePollutionUtility/path-assignment.js:71:5:71:10 | target |
1431+
| PrototypePollutionUtility/path-assignment.js:69:9:69:48 | target | PrototypePollutionUtility/path-assignment.js:71:5:71:10 | target |
1432+
| PrototypePollutionUtility/path-assignment.js:69:18:69:48 | target[ ... ] \|\| {} | PrototypePollutionUtility/path-assignment.js:69:9:69:48 | target |
1433+
| PrototypePollutionUtility/path-assignment.js:69:18:69:48 | target[ ... ] \|\| {} | PrototypePollutionUtility/path-assignment.js:69:9:69:48 | target |
1434+
| PrototypePollutionUtility/path-assignment.js:69:32:69:37 | target | PrototypePollutionUtility/path-assignment.js:69:32:69:42 | target[key] |
1435+
| PrototypePollutionUtility/path-assignment.js:69:32:69:37 | target | PrototypePollutionUtility/path-assignment.js:69:32:69:42 | target[key] |
1436+
| PrototypePollutionUtility/path-assignment.js:69:32:69:42 | target[key] | PrototypePollutionUtility/path-assignment.js:69:32:69:48 | target[key] \|\| {} |
1437+
| PrototypePollutionUtility/path-assignment.js:69:32:69:42 | target[key] | PrototypePollutionUtility/path-assignment.js:69:32:69:48 | target[key] \|\| {} |
1438+
| PrototypePollutionUtility/path-assignment.js:69:32:69:42 | target[key] | PrototypePollutionUtility/path-assignment.js:69:32:69:48 | target[key] \|\| {} |
1439+
| PrototypePollutionUtility/path-assignment.js:69:32:69:42 | target[key] | PrototypePollutionUtility/path-assignment.js:69:32:69:48 | target[key] \|\| {} |
1440+
| PrototypePollutionUtility/path-assignment.js:69:32:69:48 | target[key] \|\| {} | PrototypePollutionUtility/path-assignment.js:69:18:69:48 | target[ ... ] \|\| {} |
1441+
| PrototypePollutionUtility/path-assignment.js:69:32:69:48 | target[key] \|\| {} | PrototypePollutionUtility/path-assignment.js:69:18:69:48 | target[ ... ] \|\| {} |
1442+
| PrototypePollutionUtility/path-assignment.js:69:39:69:41 | key | PrototypePollutionUtility/path-assignment.js:69:32:69:42 | target[key] |
1443+
| PrototypePollutionUtility/path-assignment.js:69:39:69:41 | key | PrototypePollutionUtility/path-assignment.js:69:32:69:42 | target[key] |
1444+
| PrototypePollutionUtility/path-assignment.js:71:12:71:18 | keys[i] | PrototypePollutionUtility/path-assignment.js:71:12:71:18 | keys[i] |
13811445
| PrototypePollutionUtility/tests.js:3:25:3:27 | dst | PrototypePollutionUtility/tests.js:6:28:6:30 | dst |
13821446
| PrototypePollutionUtility/tests.js:3:25:3:27 | dst | PrototypePollutionUtility/tests.js:6:28:6:30 | dst |
13831447
| PrototypePollutionUtility/tests.js:3:25:3:27 | dst | PrototypePollutionUtility/tests.js:8:13:8:15 | dst |
@@ -2922,6 +2986,7 @@ edges
29222986
| PrototypePollutionUtility/path-assignment.js:15:13:15:18 | target | PrototypePollutionUtility/path-assignment.js:8:19:8:25 | keys[i] | PrototypePollutionUtility/path-assignment.js:15:13:15:18 | target | The property chain $@ is recursively assigned to $@ without guarding against prototype pollution. | PrototypePollutionUtility/path-assignment.js:8:19:8:25 | keys[i] | here | PrototypePollutionUtility/path-assignment.js:15:13:15:18 | target | target |
29232987
| PrototypePollutionUtility/path-assignment.js:44:5:44:10 | target | PrototypePollutionUtility/path-assignment.js:41:19:41:25 | keys[i] | PrototypePollutionUtility/path-assignment.js:44:5:44:10 | target | The property chain $@ is recursively assigned to $@ without guarding against prototype pollution. | PrototypePollutionUtility/path-assignment.js:41:19:41:25 | keys[i] | here | PrototypePollutionUtility/path-assignment.js:44:5:44:10 | target | target |
29242988
| PrototypePollutionUtility/path-assignment.js:61:5:61:10 | target | PrototypePollutionUtility/path-assignment.js:58:19:58:25 | keys[i] | PrototypePollutionUtility/path-assignment.js:61:5:61:10 | target | The property chain $@ is recursively assigned to $@ without guarding against prototype pollution. | PrototypePollutionUtility/path-assignment.js:58:19:58:25 | keys[i] | here | PrototypePollutionUtility/path-assignment.js:61:5:61:10 | target | target |
2989+
| PrototypePollutionUtility/path-assignment.js:71:5:71:10 | target | PrototypePollutionUtility/path-assignment.js:68:19:68:25 | keys[i] | PrototypePollutionUtility/path-assignment.js:71:5:71:10 | target | The property chain $@ is recursively assigned to $@ without guarding against prototype pollution. | PrototypePollutionUtility/path-assignment.js:68:19:68:25 | keys[i] | here | PrototypePollutionUtility/path-assignment.js:71:5:71:10 | target | target |
29252990
| PrototypePollutionUtility/tests.js:8:13:8:15 | dst | PrototypePollutionUtility/tests.js:4:14:4:16 | key | PrototypePollutionUtility/tests.js:8:13:8:15 | dst | Properties are copied from $@ to $@ without guarding against prototype pollution. | PrototypePollutionUtility/tests.js:4:21:4:23 | src | src | PrototypePollutionUtility/tests.js:8:13:8:15 | dst | dst |
29262991
| PrototypePollutionUtility/tests.js:18:13:18:15 | dst | PrototypePollutionUtility/tests.js:14:30:14:32 | key | PrototypePollutionUtility/tests.js:18:13:18:15 | dst | Properties are copied from $@ to $@ without guarding against prototype pollution. | PrototypePollutionUtility/tests.js:14:17:14:19 | src | src | PrototypePollutionUtility/tests.js:18:13:18:15 | dst | dst |
29272992
| PrototypePollutionUtility/tests.js:36:9:36:11 | dst | PrototypePollutionUtility/tests.js:25:18:25:20 | key | PrototypePollutionUtility/tests.js:36:9:36:11 | dst | Properties are copied from $@ to $@ without guarding against prototype pollution. | PrototypePollutionUtility/tests.js:25:25:25:30 | source | source | PrototypePollutionUtility/tests.js:36:9:36:11 | dst | dst |

javascript/ql/test/query-tests/Security/CWE-400/PrototypePollutionUtility/path-assignment.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,3 +60,13 @@ function assignToPathWithHelper(target, path, value, sep) {
6060
}
6161
target[keys[i]] = value; // NOT OK
6262
}
63+
64+
function spltOnRegexp(target, path, value) {
65+
let keys = path.split(/\./);
66+
let i;
67+
for (i = 0; i < keys.length - 1; ++i) {
68+
let key = keys[i];
69+
target = target[key] = target[key] || {};
70+
}
71+
target[keys[i]] = value; // NOT OK
72+
}

0 commit comments

Comments
 (0)