Skip to content

Commit f7543ae

Browse files
asger-semmleasgerf
authored andcommitted
JS: Support Reflect.ownKeys
1 parent 8af2333 commit f7543ae

File tree

3 files changed

+115
-4
lines changed

3 files changed

+115
-4
lines changed

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

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ abstract class EnumeratedPropName extends DataFlow::Node {
7171
}
7272

7373
/**
74-
* Property enumeration through `for-in` for `Object.keys` or `Object.getOwnPropertyName`.
74+
* Property enumeration through `for-in` for `Object.keys` or similar.
7575
*/
7676
class ForInEnumeratedPropName extends EnumeratedPropName {
7777
DataFlow::Node object;
@@ -82,9 +82,13 @@ class ForInEnumeratedPropName extends EnumeratedPropName {
8282
object = stmt.getIterationDomain().flow()
8383
)
8484
or
85-
exists(CallNode call, string name |
86-
call = globalVarRef("Object").getAMemberCall(name) and
87-
(name = "keys" or name = "getOwnPropertyNames") and
85+
exists(CallNode call |
86+
call = globalVarRef("Object").getAMemberCall("keys")
87+
or
88+
call = globalVarRef("Object").getAMemberCall("getOwnPropertyNames")
89+
or
90+
call = globalVarRef("Reflect").getAMemberCall("ownKeys")
91+
|
8892
object = call.getArgument(0) and
8993
this = getAnEnumeratedArrayElement(call)
9094
)

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

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -667,6 +667,46 @@ nodes
667667
| PrototypePollutionUtility/tests.js:270:24:270:28 | value |
668668
| PrototypePollutionUtility/tests.js:270:24:270:28 | value |
669669
| PrototypePollutionUtility/tests.js:270:24:270:28 | value |
670+
| PrototypePollutionUtility/tests.js:275:27:275:29 | dst |
671+
| PrototypePollutionUtility/tests.js:275:27:275:29 | dst |
672+
| PrototypePollutionUtility/tests.js:275:32:275:34 | src |
673+
| PrototypePollutionUtility/tests.js:275:32:275:34 | src |
674+
| PrototypePollutionUtility/tests.js:276:34:276:36 | key |
675+
| PrototypePollutionUtility/tests.js:276:34:276:36 | key |
676+
| PrototypePollutionUtility/tests.js:276:34:276:36 | key |
677+
| PrototypePollutionUtility/tests.js:278:30:278:32 | dst |
678+
| PrototypePollutionUtility/tests.js:278:30:278:32 | dst |
679+
| PrototypePollutionUtility/tests.js:278:30:278:37 | dst[key] |
680+
| PrototypePollutionUtility/tests.js:278:30:278:37 | dst[key] |
681+
| PrototypePollutionUtility/tests.js:278:30:278:37 | dst[key] |
682+
| PrototypePollutionUtility/tests.js:278:30:278:37 | dst[key] |
683+
| PrototypePollutionUtility/tests.js:278:34:278:36 | key |
684+
| PrototypePollutionUtility/tests.js:278:34:278:36 | key |
685+
| PrototypePollutionUtility/tests.js:278:40:278:42 | src |
686+
| PrototypePollutionUtility/tests.js:278:40:278:42 | src |
687+
| PrototypePollutionUtility/tests.js:278:40:278:47 | src[key] |
688+
| PrototypePollutionUtility/tests.js:278:40:278:47 | src[key] |
689+
| PrototypePollutionUtility/tests.js:278:40:278:47 | src[key] |
690+
| PrototypePollutionUtility/tests.js:278:40:278:47 | src[key] |
691+
| PrototypePollutionUtility/tests.js:278:40:278:47 | src[key] |
692+
| PrototypePollutionUtility/tests.js:278:44:278:46 | key |
693+
| PrototypePollutionUtility/tests.js:278:44:278:46 | key |
694+
| PrototypePollutionUtility/tests.js:280:13:280:15 | dst |
695+
| PrototypePollutionUtility/tests.js:280:13:280:15 | dst |
696+
| PrototypePollutionUtility/tests.js:280:13:280:15 | dst |
697+
| PrototypePollutionUtility/tests.js:280:17:280:19 | key |
698+
| PrototypePollutionUtility/tests.js:280:17:280:19 | key |
699+
| PrototypePollutionUtility/tests.js:280:17:280:19 | key |
700+
| PrototypePollutionUtility/tests.js:280:24:280:26 | src |
701+
| PrototypePollutionUtility/tests.js:280:24:280:26 | src |
702+
| PrototypePollutionUtility/tests.js:280:24:280:31 | src[key] |
703+
| PrototypePollutionUtility/tests.js:280:24:280:31 | src[key] |
704+
| PrototypePollutionUtility/tests.js:280:24:280:31 | src[key] |
705+
| PrototypePollutionUtility/tests.js:280:24:280:31 | src[key] |
706+
| PrototypePollutionUtility/tests.js:280:24:280:31 | src[key] |
707+
| PrototypePollutionUtility/tests.js:280:24:280:31 | src[key] |
708+
| PrototypePollutionUtility/tests.js:280:28:280:30 | key |
709+
| PrototypePollutionUtility/tests.js:280:28:280:30 | key |
670710
| examples/PrototypePollutionUtility.js:1:16:1:18 | dst |
671711
| examples/PrototypePollutionUtility.js:1:16:1:18 | dst |
672712
| examples/PrototypePollutionUtility.js:1:21:1:23 | src |
@@ -1600,6 +1640,62 @@ edges
16001640
| PrototypePollutionUtility/tests.js:268:30:268:37 | dst[key] | PrototypePollutionUtility/tests.js:263:27:263:29 | dst |
16011641
| PrototypePollutionUtility/tests.js:268:34:268:36 | key | PrototypePollutionUtility/tests.js:268:30:268:37 | dst[key] |
16021642
| PrototypePollutionUtility/tests.js:268:34:268:36 | key | PrototypePollutionUtility/tests.js:268:30:268:37 | dst[key] |
1643+
| PrototypePollutionUtility/tests.js:275:27:275:29 | dst | PrototypePollutionUtility/tests.js:278:30:278:32 | dst |
1644+
| PrototypePollutionUtility/tests.js:275:27:275:29 | dst | PrototypePollutionUtility/tests.js:278:30:278:32 | dst |
1645+
| PrototypePollutionUtility/tests.js:275:27:275:29 | dst | PrototypePollutionUtility/tests.js:280:13:280:15 | dst |
1646+
| PrototypePollutionUtility/tests.js:275:27:275:29 | dst | PrototypePollutionUtility/tests.js:280:13:280:15 | dst |
1647+
| PrototypePollutionUtility/tests.js:275:27:275:29 | dst | PrototypePollutionUtility/tests.js:280:13:280:15 | dst |
1648+
| PrototypePollutionUtility/tests.js:275:27:275:29 | dst | PrototypePollutionUtility/tests.js:280:13:280:15 | dst |
1649+
| PrototypePollutionUtility/tests.js:275:32:275:34 | src | PrototypePollutionUtility/tests.js:278:40:278:42 | src |
1650+
| PrototypePollutionUtility/tests.js:275:32:275:34 | src | PrototypePollutionUtility/tests.js:278:40:278:42 | src |
1651+
| PrototypePollutionUtility/tests.js:275:32:275:34 | src | PrototypePollutionUtility/tests.js:280:24:280:26 | src |
1652+
| PrototypePollutionUtility/tests.js:275:32:275:34 | src | PrototypePollutionUtility/tests.js:280:24:280:26 | src |
1653+
| PrototypePollutionUtility/tests.js:276:34:276:36 | key | PrototypePollutionUtility/tests.js:278:34:278:36 | key |
1654+
| PrototypePollutionUtility/tests.js:276:34:276:36 | key | PrototypePollutionUtility/tests.js:278:34:278:36 | key |
1655+
| PrototypePollutionUtility/tests.js:276:34:276:36 | key | PrototypePollutionUtility/tests.js:278:34:278:36 | key |
1656+
| PrototypePollutionUtility/tests.js:276:34:276:36 | key | PrototypePollutionUtility/tests.js:278:34:278:36 | key |
1657+
| PrototypePollutionUtility/tests.js:276:34:276:36 | key | PrototypePollutionUtility/tests.js:278:44:278:46 | key |
1658+
| PrototypePollutionUtility/tests.js:276:34:276:36 | key | PrototypePollutionUtility/tests.js:278:44:278:46 | key |
1659+
| PrototypePollutionUtility/tests.js:276:34:276:36 | key | PrototypePollutionUtility/tests.js:278:44:278:46 | key |
1660+
| PrototypePollutionUtility/tests.js:276:34:276:36 | key | PrototypePollutionUtility/tests.js:278:44:278:46 | key |
1661+
| PrototypePollutionUtility/tests.js:276:34:276:36 | key | PrototypePollutionUtility/tests.js:280:17:280:19 | key |
1662+
| PrototypePollutionUtility/tests.js:276:34:276:36 | key | PrototypePollutionUtility/tests.js:280:17:280:19 | key |
1663+
| PrototypePollutionUtility/tests.js:276:34:276:36 | key | PrototypePollutionUtility/tests.js:280:17:280:19 | key |
1664+
| PrototypePollutionUtility/tests.js:276:34:276:36 | key | PrototypePollutionUtility/tests.js:280:17:280:19 | key |
1665+
| PrototypePollutionUtility/tests.js:276:34:276:36 | key | PrototypePollutionUtility/tests.js:280:17:280:19 | key |
1666+
| PrototypePollutionUtility/tests.js:276:34:276:36 | key | PrototypePollutionUtility/tests.js:280:17:280:19 | key |
1667+
| PrototypePollutionUtility/tests.js:276:34:276:36 | key | PrototypePollutionUtility/tests.js:280:17:280:19 | key |
1668+
| PrototypePollutionUtility/tests.js:276:34:276:36 | key | PrototypePollutionUtility/tests.js:280:28:280:30 | key |
1669+
| PrototypePollutionUtility/tests.js:276:34:276:36 | key | PrototypePollutionUtility/tests.js:280:28:280:30 | key |
1670+
| PrototypePollutionUtility/tests.js:276:34:276:36 | key | PrototypePollutionUtility/tests.js:280:28:280:30 | key |
1671+
| PrototypePollutionUtility/tests.js:276:34:276:36 | key | PrototypePollutionUtility/tests.js:280:28:280:30 | key |
1672+
| PrototypePollutionUtility/tests.js:278:30:278:32 | dst | PrototypePollutionUtility/tests.js:278:30:278:37 | dst[key] |
1673+
| PrototypePollutionUtility/tests.js:278:30:278:32 | dst | PrototypePollutionUtility/tests.js:278:30:278:37 | dst[key] |
1674+
| PrototypePollutionUtility/tests.js:278:30:278:37 | dst[key] | PrototypePollutionUtility/tests.js:275:27:275:29 | dst |
1675+
| PrototypePollutionUtility/tests.js:278:30:278:37 | dst[key] | PrototypePollutionUtility/tests.js:275:27:275:29 | dst |
1676+
| PrototypePollutionUtility/tests.js:278:30:278:37 | dst[key] | PrototypePollutionUtility/tests.js:275:27:275:29 | dst |
1677+
| PrototypePollutionUtility/tests.js:278:30:278:37 | dst[key] | PrototypePollutionUtility/tests.js:275:27:275:29 | dst |
1678+
| PrototypePollutionUtility/tests.js:278:34:278:36 | key | PrototypePollutionUtility/tests.js:278:30:278:37 | dst[key] |
1679+
| PrototypePollutionUtility/tests.js:278:34:278:36 | key | PrototypePollutionUtility/tests.js:278:30:278:37 | dst[key] |
1680+
| PrototypePollutionUtility/tests.js:278:40:278:42 | src | PrototypePollutionUtility/tests.js:278:40:278:47 | src[key] |
1681+
| PrototypePollutionUtility/tests.js:278:40:278:42 | src | PrototypePollutionUtility/tests.js:278:40:278:47 | src[key] |
1682+
| PrototypePollutionUtility/tests.js:278:40:278:47 | src[key] | PrototypePollutionUtility/tests.js:275:32:275:34 | src |
1683+
| PrototypePollutionUtility/tests.js:278:40:278:47 | src[key] | PrototypePollutionUtility/tests.js:275:32:275:34 | src |
1684+
| PrototypePollutionUtility/tests.js:278:40:278:47 | src[key] | PrototypePollutionUtility/tests.js:275:32:275:34 | src |
1685+
| PrototypePollutionUtility/tests.js:278:40:278:47 | src[key] | PrototypePollutionUtility/tests.js:275:32:275:34 | src |
1686+
| PrototypePollutionUtility/tests.js:278:40:278:47 | src[key] | PrototypePollutionUtility/tests.js:275:32:275:34 | src |
1687+
| PrototypePollutionUtility/tests.js:278:40:278:47 | src[key] | PrototypePollutionUtility/tests.js:275:32:275:34 | src |
1688+
| PrototypePollutionUtility/tests.js:278:44:278:46 | key | PrototypePollutionUtility/tests.js:278:40:278:47 | src[key] |
1689+
| PrototypePollutionUtility/tests.js:278:44:278:46 | key | PrototypePollutionUtility/tests.js:278:40:278:47 | src[key] |
1690+
| PrototypePollutionUtility/tests.js:280:24:280:26 | src | PrototypePollutionUtility/tests.js:280:24:280:31 | src[key] |
1691+
| PrototypePollutionUtility/tests.js:280:24:280:26 | src | PrototypePollutionUtility/tests.js:280:24:280:31 | src[key] |
1692+
| PrototypePollutionUtility/tests.js:280:24:280:26 | src | PrototypePollutionUtility/tests.js:280:24:280:31 | src[key] |
1693+
| PrototypePollutionUtility/tests.js:280:24:280:26 | src | PrototypePollutionUtility/tests.js:280:24:280:31 | src[key] |
1694+
| PrototypePollutionUtility/tests.js:280:24:280:31 | src[key] | PrototypePollutionUtility/tests.js:280:24:280:31 | src[key] |
1695+
| PrototypePollutionUtility/tests.js:280:28:280:30 | key | PrototypePollutionUtility/tests.js:280:24:280:31 | src[key] |
1696+
| PrototypePollutionUtility/tests.js:280:28:280:30 | key | PrototypePollutionUtility/tests.js:280:24:280:31 | src[key] |
1697+
| PrototypePollutionUtility/tests.js:280:28:280:30 | key | PrototypePollutionUtility/tests.js:280:24:280:31 | src[key] |
1698+
| PrototypePollutionUtility/tests.js:280:28:280:30 | key | PrototypePollutionUtility/tests.js:280:24:280:31 | src[key] |
16031699
| examples/PrototypePollutionUtility.js:1:16:1:18 | dst | examples/PrototypePollutionUtility.js:5:19:5:21 | dst |
16041700
| examples/PrototypePollutionUtility.js:1:16:1:18 | dst | examples/PrototypePollutionUtility.js:5:19:5:21 | dst |
16051701
| examples/PrototypePollutionUtility.js:1:16:1:18 | dst | examples/PrototypePollutionUtility.js:7:13:7:15 | dst |
@@ -1716,4 +1812,5 @@ edges
17161812
| PrototypePollutionUtility/tests.js:196:13:196:15 | dst | PrototypePollutionUtility/tests.js:192:19:192:25 | keys[i] | PrototypePollutionUtility/tests.js:196:13:196:15 | dst | Properties are copied from $@ to $@ without guarding against prototype pollution. | PrototypePollutionUtility/tests.js:190:28:190:30 | src | src | PrototypePollutionUtility/tests.js:196:13:196:15 | dst | dst |
17171813
| PrototypePollutionUtility/tests.js:233:5:233:13 | map[key1] | PrototypePollutionUtility/tests.js:238:14:238:16 | key | PrototypePollutionUtility/tests.js:233:5:233:13 | map[key1] | Properties are copied from $@ to $@ without guarding against prototype pollution. | PrototypePollutionUtility/tests.js:238:21:238:24 | data | data | PrototypePollutionUtility/tests.js:233:5:233:13 | map[key1] | this object |
17181814
| PrototypePollutionUtility/tests.js:270:13:270:15 | dst | PrototypePollutionUtility/tests.js:265:19:265:26 | entry[0] | PrototypePollutionUtility/tests.js:270:13:270:15 | dst | Properties are copied from $@ to $@ without guarding against prototype pollution. | PrototypePollutionUtility/tests.js:264:20:264:22 | src | src | PrototypePollutionUtility/tests.js:270:13:270:15 | dst | dst |
1815+
| PrototypePollutionUtility/tests.js:280:13:280:15 | dst | PrototypePollutionUtility/tests.js:276:34:276:36 | key | PrototypePollutionUtility/tests.js:280:13:280:15 | dst | Properties are copied from $@ to $@ without guarding against prototype pollution. | PrototypePollutionUtility/tests.js:276:21:276:23 | src | src | PrototypePollutionUtility/tests.js:280:13:280:15 | dst | dst |
17191816
| examples/PrototypePollutionUtility.js:7:13:7:15 | dst | examples/PrototypePollutionUtility.js:2:14:2:16 | key | examples/PrototypePollutionUtility.js:7:13:7:15 | dst | Properties are copied from $@ to $@ without guarding against prototype pollution. | examples/PrototypePollutionUtility.js:2:21:2:23 | src | src | examples/PrototypePollutionUtility.js:7:13:7:15 | dst | dst |

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -271,3 +271,13 @@ function copyUsingEntries(dst, src) {
271271
}
272272
});
273273
}
274+
275+
function copyUsingReflect(dst, src) {
276+
Reflect.ownKeys(src).forEach(key => {
277+
if (dst[key]) {
278+
copyUsingReflect(dst[key], src[key]);
279+
} else {
280+
dst[key] = src[key]; // NOT OK
281+
}
282+
});
283+
}

0 commit comments

Comments
 (0)