Merge pull request #8946 from kaeluka/deepFillIn-FN

JS: fix a FN for prototype polluting function query
This commit is contained in:
Stephan Brandauer
2022-04-29 10:14:41 +01:00
committed by GitHub
3 changed files with 198 additions and 9 deletions

View File

@@ -518,7 +518,9 @@ predicate isPrototypePollutingAssignment(Node base, Node prop, Node rhs, Node pr
if propNameSource instanceof EnumeratedPropName
then
cfg.hasFlow(propNameSource, prop) and
cfg.hasFlow(propNameSource.(EnumeratedPropName).getASourceProp(), rhs)
cfg.hasFlow([propNameSource, AccessPath::getAnAliasedSourceNode(propNameSource)]
.(EnumeratedPropName)
.getASourceProp(), rhs)
else (
cfg.hasFlow(propNameSource.(SplitPropName).getAnAlias(), prop) and
rhs.getALocalSource() instanceof ParameterNode
@@ -567,27 +569,27 @@ class ObjectCreateNullCall extends CallNode {
}
from
PropNameTracking cfg, DataFlow::PathNode source, DataFlow::PathNode sink, Node prop, Node base,
string msg, Node col1, Node col2
PropNameTracking cfg, DataFlow::PathNode source, DataFlow::PathNode sink, Node propNameSource,
Node base, string msg, Node col1, Node col2
where
isPollutedPropName(prop) and
isPollutedPropName(propNameSource) and
cfg.hasFlowPath(source, sink) and
isPrototypePollutingAssignment(base, _, _, prop) and
isPrototypePollutingAssignment(base, _, _, propNameSource) and
sink.getNode() = base and
source.getNode() = prop and
source.getNode() = propNameSource and
(
getANodeLeadingToBaseBase(base) instanceof ObjectLiteralNode
or
not getANodeLeadingToBaseBase(base) instanceof ObjectCreateNullCall
) and
// Generate different messages for deep merge and deep assign cases.
if prop instanceof EnumeratedPropName
if propNameSource instanceof EnumeratedPropName
then (
col1 = prop.(EnumeratedPropName).getSourceObject() and
col1 = propNameSource.(EnumeratedPropName).getSourceObject() and
col2 = base and
msg = "Properties are copied from $@ to $@ without guarding against prototype pollution."
) else (
col1 = prop and
col1 = propNameSource and
col2 = base and
msg =
"The property chain $@ is recursively assigned to $@ without guarding against prototype pollution."

View File

@@ -1406,6 +1406,78 @@ nodes
| tests.js:529:24:529:31 | src[key] |
| tests.js:529:28:529:30 | key |
| tests.js:529:28:529:30 | key |
| tests.js:534:31:534:33 | obj |
| tests.js:534:31:534:33 | obj |
| tests.js:534:31:534:33 | obj |
| tests.js:534:31:534:33 | obj |
| tests.js:538:18:538:24 | keys[i] |
| tests.js:538:18:538:24 | keys[i] |
| tests.js:538:18:538:24 | keys[i] |
| tests.js:538:27:538:29 | obj |
| tests.js:538:27:538:29 | obj |
| tests.js:538:27:538:29 | obj |
| tests.js:538:27:538:29 | obj |
| tests.js:538:27:538:38 | obj[keys[i]] |
| tests.js:538:27:538:38 | obj[keys[i]] |
| tests.js:538:27:538:38 | obj[keys[i]] |
| tests.js:538:27:538:38 | obj[keys[i]] |
| tests.js:538:27:538:38 | obj[keys[i]] |
| tests.js:538:27:538:38 | obj[keys[i]] |
| tests.js:538:27:538:38 | obj[keys[i]] |
| tests.js:538:31:538:37 | keys[i] |
| tests.js:538:31:538:37 | keys[i] |
| tests.js:538:31:538:37 | keys[i] |
| tests.js:542:30:542:32 | dst |
| tests.js:542:30:542:32 | dst |
| tests.js:542:30:542:32 | dst |
| tests.js:542:30:542:32 | dst |
| tests.js:542:35:542:37 | src |
| tests.js:542:35:542:37 | src |
| tests.js:542:35:542:37 | src |
| tests.js:542:35:542:37 | src |
| tests.js:543:26:543:28 | src |
| tests.js:543:26:543:28 | src |
| tests.js:543:26:543:28 | src |
| tests.js:543:26:543:28 | src |
| tests.js:543:32:543:34 | key |
| tests.js:543:32:543:34 | key |
| tests.js:543:32:543:34 | key |
| tests.js:543:32:543:34 | key |
| tests.js:543:37:543:41 | value |
| tests.js:543:37:543:41 | value |
| tests.js:543:37:543:41 | value |
| tests.js:543:37:543:41 | value |
| tests.js:545:33:545:35 | dst |
| tests.js:545:33:545:35 | dst |
| tests.js:545:33:545:35 | dst |
| tests.js:545:33:545:35 | dst |
| tests.js:545:33:545:40 | dst[key] |
| tests.js:545:33:545:40 | dst[key] |
| tests.js:545:33:545:40 | dst[key] |
| tests.js:545:33:545:40 | dst[key] |
| tests.js:545:37:545:39 | key |
| tests.js:545:37:545:39 | key |
| tests.js:545:37:545:39 | key |
| tests.js:545:37:545:39 | key |
| tests.js:545:43:545:47 | value |
| tests.js:545:43:545:47 | value |
| tests.js:545:43:545:47 | value |
| tests.js:545:43:545:47 | value |
| tests.js:547:13:547:15 | dst |
| tests.js:547:13:547:15 | dst |
| tests.js:547:13:547:15 | dst |
| tests.js:547:13:547:15 | dst |
| tests.js:547:13:547:15 | dst |
| tests.js:547:17:547:19 | key |
| tests.js:547:17:547:19 | key |
| tests.js:547:17:547:19 | key |
| tests.js:547:17:547:19 | key |
| tests.js:547:17:547:19 | key |
| tests.js:547:24:547:28 | value |
| tests.js:547:24:547:28 | value |
| tests.js:547:24:547:28 | value |
| tests.js:547:24:547:28 | value |
| tests.js:547:24:547:28 | value |
edges
| examples/PrototypePollutingFunction.js:1:16:1:18 | dst | examples/PrototypePollutingFunction.js:5:19:5:21 | dst |
| examples/PrototypePollutingFunction.js:1:16:1:18 | dst | examples/PrototypePollutingFunction.js:5:19:5:21 | dst |
@@ -3179,6 +3251,102 @@ edges
| tests.js:529:28:529:30 | key | tests.js:529:24:529:31 | src[key] |
| tests.js:529:28:529:30 | key | tests.js:529:24:529:31 | src[key] |
| tests.js:529:28:529:30 | key | tests.js:529:24:529:31 | src[key] |
| tests.js:534:31:534:33 | obj | tests.js:538:27:538:29 | obj |
| tests.js:534:31:534:33 | obj | tests.js:538:27:538:29 | obj |
| tests.js:534:31:534:33 | obj | tests.js:538:27:538:29 | obj |
| tests.js:534:31:534:33 | obj | tests.js:538:27:538:29 | obj |
| tests.js:538:18:538:24 | keys[i] | tests.js:543:32:543:34 | key |
| tests.js:538:18:538:24 | keys[i] | tests.js:543:32:543:34 | key |
| tests.js:538:18:538:24 | keys[i] | tests.js:543:32:543:34 | key |
| tests.js:538:18:538:24 | keys[i] | tests.js:543:32:543:34 | key |
| tests.js:538:18:538:24 | keys[i] | tests.js:543:32:543:34 | key |
| tests.js:538:18:538:24 | keys[i] | tests.js:543:32:543:34 | key |
| tests.js:538:18:538:24 | keys[i] | tests.js:543:32:543:34 | key |
| tests.js:538:18:538:24 | keys[i] | tests.js:543:32:543:34 | key |
| tests.js:538:27:538:29 | obj | tests.js:538:27:538:38 | obj[keys[i]] |
| tests.js:538:27:538:29 | obj | tests.js:538:27:538:38 | obj[keys[i]] |
| tests.js:538:27:538:29 | obj | tests.js:538:27:538:38 | obj[keys[i]] |
| tests.js:538:27:538:29 | obj | tests.js:538:27:538:38 | obj[keys[i]] |
| tests.js:538:27:538:38 | obj[keys[i]] | tests.js:543:37:543:41 | value |
| tests.js:538:27:538:38 | obj[keys[i]] | tests.js:543:37:543:41 | value |
| tests.js:538:27:538:38 | obj[keys[i]] | tests.js:543:37:543:41 | value |
| tests.js:538:27:538:38 | obj[keys[i]] | tests.js:543:37:543:41 | value |
| tests.js:538:27:538:38 | obj[keys[i]] | tests.js:543:37:543:41 | value |
| tests.js:538:27:538:38 | obj[keys[i]] | tests.js:543:37:543:41 | value |
| tests.js:538:27:538:38 | obj[keys[i]] | tests.js:543:37:543:41 | value |
| tests.js:538:27:538:38 | obj[keys[i]] | tests.js:543:37:543:41 | value |
| tests.js:538:27:538:38 | obj[keys[i]] | tests.js:543:37:543:41 | value |
| tests.js:538:27:538:38 | obj[keys[i]] | tests.js:543:37:543:41 | value |
| tests.js:538:27:538:38 | obj[keys[i]] | tests.js:543:37:543:41 | value |
| tests.js:538:27:538:38 | obj[keys[i]] | tests.js:543:37:543:41 | value |
| tests.js:538:31:538:37 | keys[i] | tests.js:538:27:538:38 | obj[keys[i]] |
| tests.js:538:31:538:37 | keys[i] | tests.js:538:27:538:38 | obj[keys[i]] |
| tests.js:538:31:538:37 | keys[i] | tests.js:538:27:538:38 | obj[keys[i]] |
| tests.js:538:31:538:37 | keys[i] | tests.js:538:27:538:38 | obj[keys[i]] |
| tests.js:542:30:542:32 | dst | tests.js:545:33:545:35 | dst |
| tests.js:542:30:542:32 | dst | tests.js:545:33:545:35 | dst |
| tests.js:542:30:542:32 | dst | tests.js:545:33:545:35 | dst |
| tests.js:542:30:542:32 | dst | tests.js:545:33:545:35 | dst |
| tests.js:542:30:542:32 | dst | tests.js:547:13:547:15 | dst |
| tests.js:542:30:542:32 | dst | tests.js:547:13:547:15 | dst |
| tests.js:542:30:542:32 | dst | tests.js:547:13:547:15 | dst |
| tests.js:542:30:542:32 | dst | tests.js:547:13:547:15 | dst |
| tests.js:542:30:542:32 | dst | tests.js:547:13:547:15 | dst |
| tests.js:542:30:542:32 | dst | tests.js:547:13:547:15 | dst |
| tests.js:542:30:542:32 | dst | tests.js:547:13:547:15 | dst |
| tests.js:542:30:542:32 | dst | tests.js:547:13:547:15 | dst |
| tests.js:542:35:542:37 | src | tests.js:543:26:543:28 | src |
| tests.js:542:35:542:37 | src | tests.js:543:26:543:28 | src |
| tests.js:542:35:542:37 | src | tests.js:543:26:543:28 | src |
| tests.js:542:35:542:37 | src | tests.js:543:26:543:28 | src |
| tests.js:543:26:543:28 | src | tests.js:534:31:534:33 | obj |
| tests.js:543:26:543:28 | src | tests.js:534:31:534:33 | obj |
| tests.js:543:26:543:28 | src | tests.js:534:31:534:33 | obj |
| tests.js:543:26:543:28 | src | tests.js:534:31:534:33 | obj |
| tests.js:543:26:543:28 | src | tests.js:543:37:543:41 | value |
| tests.js:543:26:543:28 | src | tests.js:543:37:543:41 | value |
| tests.js:543:26:543:28 | src | tests.js:543:37:543:41 | value |
| tests.js:543:26:543:28 | src | tests.js:543:37:543:41 | value |
| tests.js:543:32:543:34 | key | tests.js:545:37:545:39 | key |
| tests.js:543:32:543:34 | key | tests.js:545:37:545:39 | key |
| tests.js:543:32:543:34 | key | tests.js:545:37:545:39 | key |
| tests.js:543:32:543:34 | key | tests.js:545:37:545:39 | key |
| tests.js:543:32:543:34 | key | tests.js:547:17:547:19 | key |
| tests.js:543:32:543:34 | key | tests.js:547:17:547:19 | key |
| tests.js:543:32:543:34 | key | tests.js:547:17:547:19 | key |
| tests.js:543:32:543:34 | key | tests.js:547:17:547:19 | key |
| tests.js:543:32:543:34 | key | tests.js:547:17:547:19 | key |
| tests.js:543:32:543:34 | key | tests.js:547:17:547:19 | key |
| tests.js:543:32:543:34 | key | tests.js:547:17:547:19 | key |
| tests.js:543:32:543:34 | key | tests.js:547:17:547:19 | key |
| tests.js:543:37:543:41 | value | tests.js:545:43:545:47 | value |
| tests.js:543:37:543:41 | value | tests.js:545:43:545:47 | value |
| tests.js:543:37:543:41 | value | tests.js:545:43:545:47 | value |
| tests.js:543:37:543:41 | value | tests.js:545:43:545:47 | value |
| tests.js:543:37:543:41 | value | tests.js:547:24:547:28 | value |
| tests.js:543:37:543:41 | value | tests.js:547:24:547:28 | value |
| tests.js:543:37:543:41 | value | tests.js:547:24:547:28 | value |
| tests.js:543:37:543:41 | value | tests.js:547:24:547:28 | value |
| tests.js:543:37:543:41 | value | tests.js:547:24:547:28 | value |
| tests.js:543:37:543:41 | value | tests.js:547:24:547:28 | value |
| tests.js:543:37:543:41 | value | tests.js:547:24:547:28 | value |
| tests.js:543:37:543:41 | value | tests.js:547:24:547:28 | value |
| tests.js:545:33:545:35 | dst | tests.js:545:33:545:40 | dst[key] |
| tests.js:545:33:545:35 | dst | tests.js:545:33:545:40 | dst[key] |
| tests.js:545:33:545:35 | dst | tests.js:545:33:545:40 | dst[key] |
| tests.js:545:33:545:35 | dst | tests.js:545:33:545:40 | dst[key] |
| tests.js:545:33:545:40 | dst[key] | tests.js:542:30:542:32 | dst |
| tests.js:545:33:545:40 | dst[key] | tests.js:542:30:542:32 | dst |
| tests.js:545:33:545:40 | dst[key] | tests.js:542:30:542:32 | dst |
| tests.js:545:33:545:40 | dst[key] | tests.js:542:30:542:32 | dst |
| tests.js:545:37:545:39 | key | tests.js:545:33:545:40 | dst[key] |
| tests.js:545:37:545:39 | key | tests.js:545:33:545:40 | dst[key] |
| tests.js:545:37:545:39 | key | tests.js:545:33:545:40 | dst[key] |
| tests.js:545:37:545:39 | key | tests.js:545:33:545:40 | dst[key] |
| tests.js:545:43:545:47 | value | tests.js:542:35:542:37 | src |
| tests.js:545:43:545:47 | value | tests.js:542:35:542:37 | src |
| tests.js:545:43:545:47 | value | tests.js:542:35:542:37 | src |
| tests.js:545:43:545:47 | value | tests.js:542:35:542:37 | src |
#select
| examples/PrototypePollutingFunction.js:7:13:7:15 | dst | examples/PrototypePollutingFunction.js:2:14:2:16 | key | examples/PrototypePollutingFunction.js:7:13:7:15 | dst | Properties are copied from $@ to $@ without guarding against prototype pollution. | examples/PrototypePollutingFunction.js:2:21:2:23 | src | src | examples/PrototypePollutingFunction.js:7:13:7:15 | dst | dst |
| path-assignment.js:15:13:15:18 | target | path-assignment.js:8:19:8:25 | keys[i] | path-assignment.js:15:13:15:18 | target | The property chain $@ is recursively assigned to $@ without guarding against prototype pollution. | path-assignment.js:8:19:8:25 | keys[i] | here | path-assignment.js:15:13:15:18 | target | target |
@@ -3209,3 +3377,4 @@ edges
| tests.js:489:13:489:15 | dst | tests.js:484:14:484:16 | key | tests.js:489:13:489:15 | dst | Properties are copied from $@ to $@ without guarding against prototype pollution. | tests.js:484:21:484:23 | src | src | tests.js:489:13:489:15 | dst | dst |
| tests.js:517:35:517:37 | dst | tests.js:511:19:511:25 | keys[i] | tests.js:517:35:517:37 | dst | Properties are copied from $@ to $@ without guarding against prototype pollution. | tests.js:509:28:509:30 | src | src | tests.js:517:35:517:37 | dst | dst |
| tests.js:529:13:529:15 | dst | tests.js:525:14:525:16 | key | tests.js:529:13:529:15 | dst | Properties are copied from $@ to $@ without guarding against prototype pollution. | tests.js:525:21:525:23 | src | src | tests.js:529:13:529:15 | dst | dst |
| tests.js:547:13:547:15 | dst | tests.js:538:18:538:24 | keys[i] | tests.js:547:13:547:15 | dst | Properties are copied from $@ to $@ without guarding against prototype pollution. | tests.js:535:30:535:32 | obj | obj | tests.js:547:13:547:15 | dst | dst |

View File

@@ -530,3 +530,21 @@ function copyUsingForInAndRest(...args) {
}
}
}
function forEachPropNoTempVar(obj, callback) {
const keys = Object.keys(obj)
const len = keys.length
for (let i = 0; i < len; i++) {
callback(keys[i], obj[keys[i]])
}
}
function mergeUsingCallback3(dst, src) {
forEachPropNoTempVar(src, (key, value) => {
if (dst[key]) {
mergeUsingCallback3(dst[key], value);
} else {
dst[key] = value; // NOT OK
}
});
}