JS: Support spread arguments in array.splice

This commit is contained in:
Rasmus Wriedt Larsen
2024-06-14 15:26:01 +02:00
parent 269f8ca2cd
commit 3f2befc3e5
3 changed files with 21 additions and 2 deletions

View File

@@ -77,10 +77,14 @@ module ArrayTaintTracking {
succ = call.getReceiver().getALocalSource() and
call.getCalleeName() = ["push", "unshift"]
or
// `array.splice(i, del, ...items)`: if any item is tainted, then so is `array`.
// `array.splice(i, del, e1, e2, ...)`: if any item is tainted, then so is `array`.
pred = call.getArgument(any(int i | i >= 2)) and
succ.(DataFlow::SourceNode).getAMethodCall("splice") = call
or
// `array.splice(i, del, ...e)`: if `e` is tainted, then so is `array`.
pred = call.getASpreadArgument() and
succ.(DataFlow::SourceNode).getAMethodCall("splice") = call
or
// `e = array.pop()`, `e = array.shift()`, or similar: if `array` is tainted, then so is `e`.
call.(DataFlow::MethodCallNode).calls(pred, ["pop", "shift", "slice", "splice", "at"]) and
succ = call
@@ -274,7 +278,7 @@ private module ArrayDataFlow {
/**
* A step modeling that `splice` can insert elements into an array.
* For example in `array.splice(i, del, ...items)`: if any item is tainted, then so is `array`
* For example in `array.splice(i, del, e1, e2, ...)`: if any item is tainted, then so is `array`
*/
private class ArraySpliceStep extends PreCallGraphStep {
override predicate storeStep(DataFlow::Node element, DataFlow::SourceNode obj, string prop) {
@@ -285,6 +289,19 @@ private module ArrayDataFlow {
call = obj.getAMethodCall()
)
}
override predicate loadStoreStep(
DataFlow::Node pred, DataFlow::SourceNode succ, string fromProp, string toProp
) {
fromProp = arrayLikeElement() and
toProp = arrayElement() and
// `array.splice(i, del, ...arr)` variant
exists(DataFlow::MethodCallNode mcn |
mcn.getMethodName() = "splice" and
pred = mcn.getASpreadArgument() and
succ = mcn.getReceiver().getALocalSource()
)
}
}
/**

View File

@@ -3,6 +3,7 @@
| arrays.js:2:16:2:23 | "source" | arrays.js:15:27:15:27 | e |
| arrays.js:2:16:2:23 | "source" | arrays.js:16:23:16:23 | e |
| arrays.js:2:16:2:23 | "source" | arrays.js:20:8:20:16 | arr.pop() |
| arrays.js:2:16:2:23 | "source" | arrays.js:39:8:39:24 | arr4_spread.pop() |
| arrays.js:2:16:2:23 | "source" | arrays.js:61:10:61:10 | x |
| arrays.js:2:16:2:23 | "source" | arrays.js:65:10:65:10 | x |
| arrays.js:2:16:2:23 | "source" | arrays.js:69:10:69:10 | x |

View File

@@ -3,6 +3,7 @@
| arrays.js:2:16:2:23 | "source" | arrays.js:15:27:15:27 | e |
| arrays.js:2:16:2:23 | "source" | arrays.js:16:23:16:23 | e |
| arrays.js:2:16:2:23 | "source" | arrays.js:20:8:20:16 | arr.pop() |
| arrays.js:2:16:2:23 | "source" | arrays.js:39:8:39:24 | arr4_spread.pop() |
| arrays.js:2:16:2:23 | "source" | arrays.js:58:8:58:13 | arr[0] |
| arrays.js:2:16:2:23 | "source" | arrays.js:61:10:61:10 | x |
| arrays.js:2:16:2:23 | "source" | arrays.js:65:10:65:10 | x |