Skip to content

Commit 565dde2

Browse files
committed
Fix a regression where the alert was not made if a child CQL clause is tainted
For example, this example was not alerted on: ``` javascript this.on("send00234", async (req) => { const { id } = req.data; const { Service1Entity } = this.entities; await UPDATE.entity(Service1Entity).set("col1 = col1 + " + id).where`ID = ${id}`; // UNSAFE: direct concatenation with `+` }); ```
1 parent 66ef528 commit 565dde2

File tree

2 files changed

+19
-3
lines changed

2 files changed

+19
-3
lines changed

javascript/frameworks/cap/lib/advanced_security/javascript/frameworks/cap/CAPCqlInjectionQuery.qll

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,15 +36,20 @@ class AwaitCqlClauseWithStringConcatParameter extends CqlInjectionSink {
3636
DataFlow::Node queryParameter;
3737
DataFlow::Node query;
3838
CqlClauseWithStringConcatParameter cqlClauseWithStringConcat;
39+
CqlClause finalAncestorCqlClauseOfCqlClauseWithStringConcat;
3940

4041
AwaitCqlClauseWithStringConcatParameter() {
4142
exists(AwaitExpr await |
4243
this = await.flow() and
43-
await.getOperand() = cqlClauseWithStringConcat.(CqlClause).asExpr()
44+
await.getOperand() = finalAncestorCqlClauseOfCqlClauseWithStringConcat.asExpr() and
45+
finalAncestorCqlClauseOfCqlClauseWithStringConcat =
46+
cqlClauseWithStringConcat.(CqlClause).getFinalClause()
4447
)
4548
}
4649

47-
override DataFlow::Node getQuery() { result = cqlClauseWithStringConcat.(CqlClause).flow() }
50+
override DataFlow::Node getQuery() {
51+
result = finalAncestorCqlClauseOfCqlClauseWithStringConcat.flow()
52+
}
4853
}
4954

5055
/**
@@ -189,7 +194,7 @@ class CqlInjectionConfiguration extends TaintTracking::Configuration {
189194

190195
exists(CqlClause cqlClause |
191196
start = cqlClause.getArgument().flow().getAPredecessor*().(StringOps::Concatenation) and
192-
end = cqlClause.flow()
197+
end = cqlClause.getFinalClause().flow()
193198
)
194199
}
195200
}

javascript/frameworks/cap/lib/advanced_security/javascript/frameworks/cap/CQL.qll

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,17 @@ class CqlClause extends TCqlClause {
264264

265265
predicate isFinal() { not exists(this.getParentCqlClause()) }
266266

267+
/**
268+
* Gets the final CQL clause that this clause is a part of.
269+
*/
270+
CqlClause getFinalClause() {
271+
if this.isFinal()
272+
then result = this
273+
else (
274+
result = this.getAnAncestorCqlClause() and result.isFinal()
275+
)
276+
}
277+
267278
/**
268279
* Matches the given `CqlClause` to its method/property name, nested at arbitrary depth.
269280
*/

0 commit comments

Comments
 (0)