Skip to content

Commit e2cd7e6

Browse files
committed
more precise taint-tracking for Promise.all
1 parent 3138918 commit e2cd7e6

File tree

4 files changed

+17
-17
lines changed

4 files changed

+17
-17
lines changed

javascript/ql/src/semmle/javascript/Promises.qll

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -476,7 +476,11 @@ predicate promiseTaintStep(DataFlow::Node pred, DataFlow::Node succ) {
476476
pred = succ.(PromiseDefinition).getResolveParameter().getACall().getArgument(0)
477477
or
478478
// from `x` to `Promise.resolve(x)`
479-
pred = succ.(PromiseCreationCall).getValue()
479+
pred = succ.(PromiseCreationCall).getValue() and
480+
not succ instanceof PromiseAllCreation
481+
or
482+
// from `arr` to `Promise.all(arr)`
483+
pred = succ.(PromiseAllCreation).getArrayNode()
480484
or
481485
exists(DataFlow::MethodCallNode thn | thn.getMethodName() = "then" |
482486
// from `p` to `x` in `p.then(x => ...)`

javascript/ql/src/semmle/javascript/dataflow/TaintTracking.qll

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -241,9 +241,6 @@ module TaintTracking {
241241
*/
242242
private predicate heapStep(DataFlow::Node pred, DataFlow::Node succ) {
243243
exists(Expr e, Expr f | e = succ.asExpr() and f = pred.asExpr() |
244-
// arrays with tainted elements and objects with tainted property names are tainted
245-
e.(ArrayExpr).getAnElement() = f
246-
or
247244
exists(Property prop | e.(ObjectExpr).getAProperty() = prop |
248245
prop.isComputed() and f = prop.getNameExpr()
249246
)
@@ -258,6 +255,10 @@ module TaintTracking {
258255
e.(ArrayExpr).getAnElement().(SpreadElement).getOperand() = f
259256
)
260257
or
258+
// arrays with tainted elements and objects with tainted property names are tainted
259+
succ.(DataFlow::ArrayCreationNode).getAnElement() = pred and
260+
not any(PromiseAllCreation call).getArrayNode() = succ
261+
or
261262
// reading from a tainted object yields a tainted result
262263
succ.(DataFlow::PropRead).getBase() = pred
263264
or

javascript/ql/test/library-tests/Promises/flow2.js

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,20 @@
22
var source = "source";
33

44
Promise.all([source, "clean"]).then((arr) => {
5-
sink(arr); // OK - but flagged by taint-tracking.
5+
sink(arr); // OK
66
sink(arr[0]); // NOT OK
7-
sink(arr[1]); // OK - but flagged by taint-tracking.
7+
sink(arr[1]); // OK
88
})
99

1010
var [clean, tainted] = await Promise.all(["clean", source]);
11-
sink(clean); // OK - but flagged by taint-tracking
11+
sink(clean); // OK
1212
sink(tainted); // NOT OK
1313

1414
var [clean2, tainted2] = await Promise.resolve(Promise.all(["clean", source]));
15-
sink(clean2); // OK - but flagged by taint-tracking
15+
sink(clean2); // OK
1616
sink(tainted2); // NOT OK
1717

18-
var [clean2, tainted2] = await Promise.all(["clean", Promise.resolve(source)]);
19-
sink(clean2); // OK - but flagged by taint-tracking
20-
sink(tainted2); // NOT OK - but only flagged by taint-tracking
18+
var [clean3, tainted3] = await Promise.all(["clean", Promise.resolve(source)]);
19+
sink(clean3); // OK
20+
sink(tainted3); // NOT OK - but only flagged by taint-tracking
2121
});

javascript/ql/test/library-tests/Promises/tests.expected

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -233,12 +233,7 @@ flow
233233
| flow.js:2:15:2:22 | "source" | flow.js:129:69:129:69 | x |
234234
| flow.js:2:15:2:22 | "source" | flow.js:131:43:131:43 | x |
235235
exclusiveTaintFlow
236-
| flow2.js:2:15:2:22 | "source" | flow2.js:5:8:5:10 | arr |
237-
| flow2.js:2:15:2:22 | "source" | flow2.js:7:8:7:13 | arr[1] |
238-
| flow2.js:2:15:2:22 | "source" | flow2.js:11:7:11:11 | clean |
239-
| flow2.js:2:15:2:22 | "source" | flow2.js:15:7:15:12 | clean2 |
240-
| flow2.js:2:15:2:22 | "source" | flow2.js:19:7:19:12 | clean2 |
241-
| flow2.js:2:15:2:22 | "source" | flow2.js:20:7:20:14 | tainted2 |
236+
| flow2.js:2:15:2:22 | "source" | flow2.js:20:7:20:14 | tainted3 |
242237
| interflow.js:3:18:3:25 | "source" | interflow.js:18:10:18:14 | error |
243238
typetrack
244239
| flow2.js:4:2:4:31 | Promise ... lean"]) | flow2.js:4:14:4:30 | [source, "clean"] | copy $PromiseResolveField$ |

0 commit comments

Comments
 (0)