Skip to content

Commit 5d52200

Browse files
committed
Factor out sink definition in a class and associate location reporting to it
This avoids duplicating the sink definition in `getQueryOfSink` and also in the `isSink` of the configuration.
1 parent cee86f1 commit 5d52200

File tree

3 files changed

+47
-37
lines changed

3 files changed

+47
-37
lines changed

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

Lines changed: 43 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,14 @@ import advanced_security.javascript.frameworks.cap.CQL
44
import advanced_security.javascript.frameworks.cap.RemoteFlowSources
55
import advanced_security.javascript.frameworks.cap.dataflow.FlowSteps
66

7+
abstract class CqlInjectionSink extends DataFlow::Node {
8+
/**
9+
* Gets the data flow node that represents the query being run, for
10+
* accurate reporting.
11+
*/
12+
abstract DataFlow::Node getQuery();
13+
}
14+
715
/**
816
* A CQL clause parameterized with a string concatentation expression.
917
*/
@@ -26,12 +34,35 @@ class CqlClauseWithStringConcatParameter instanceof CqlClause {
2634
string toString() { result = super.toString() }
2735
}
2836

37+
class AwaitCqlClauseWithStringConcatParameter extends CqlInjectionSink {
38+
DataFlow::Node queryParameter;
39+
DataFlow::Node query;
40+
CqlClauseWithStringConcatParameter cqlClauseWithStringConcat;
41+
42+
AwaitCqlClauseWithStringConcatParameter() {
43+
exists(AwaitExpr await |
44+
this = await.flow() and
45+
await.getOperand() = cqlClauseWithStringConcat.(CqlClause).asExpr()
46+
)
47+
}
48+
49+
override DataFlow::Node getQuery() { result = cqlClauseWithStringConcat.(CqlClause).flow() }
50+
}
51+
52+
class ParameterOfCqlRunMethodQueryArgument extends CqlInjectionSink {
53+
CqlRunMethodCall cqlRunMethodCall;
54+
55+
ParameterOfCqlRunMethodQueryArgument() { this = cqlRunMethodCall.getAQueryParameter() }
56+
57+
override DataFlow::Node getQuery() { result = this }
58+
}
59+
2960
/**
3061
* A CQL shortcut method call (`read`, `create`, ...) parameterized with a string
3162
* concatenation expression.
3263
*/
3364
class CqlShortcutMethodCallWithStringConcat instanceof CqlShortcutMethodCall {
34-
DataFlow::Node stringConcatParameter;
65+
DataFlow::Node stringConcatParameter;
3566

3667
CqlShortcutMethodCallWithStringConcat() {
3768
stringConcatParameter = super.getAQueryParameter() and
@@ -45,6 +76,16 @@ class CqlShortcutMethodCallWithStringConcat instanceof CqlShortcutMethodCall {
4576
DataFlow::Node getStringConcatParameter() { result = stringConcatParameter }
4677
}
4778

79+
class StringConcatParameterOfCqlShortcutMethodCall extends CqlInjectionSink {
80+
CqlShortcutMethodCallWithStringConcat cqlShortcutMethodCallWithStringConcat;
81+
82+
StringConcatParameterOfCqlShortcutMethodCall() {
83+
this = cqlShortcutMethodCallWithStringConcat.getStringConcatParameter()
84+
}
85+
86+
override DataFlow::Node getQuery() { result = cqlShortcutMethodCallWithStringConcat }
87+
}
88+
4889
/**
4990
* A CQL parser call (`cds.ql`, `cds.parse.cql`, ...) parameterized with a string
5091
* conatenation expression.
@@ -65,20 +106,7 @@ class CqlInjectionConfiguration extends TaintTracking::Configuration {
65106

66107
override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
67108

68-
override predicate isSink(DataFlow::Node node) {
69-
exists(CqlRunMethodCall cqlRunMethodCall |
70-
node = cqlRunMethodCall.(CqlRunMethodCall).getAQueryParameter()
71-
)
72-
or
73-
exists(CqlShortcutMethodCallWithStringConcat queryRunnerCall |
74-
node = queryRunnerCall.getStringConcatParameter()
75-
)
76-
or
77-
exists(AwaitExpr await, CqlClauseWithStringConcatParameter cqlClauseWithStringConcat |
78-
node = await.flow() and
79-
await.getOperand() = cqlClauseWithStringConcat.(CqlClause).asExpr()
80-
)
81-
}
109+
override predicate isSink(DataFlow::Node node) { node instanceof CqlInjectionSink }
82110

83111
override predicate isSanitizer(DataFlow::Node node) { node instanceof SqlInjection::Sanitizer }
84112

javascript/frameworks/cap/src/cqlinjection/CqlInjection.ql

Lines changed: 2 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -14,25 +14,7 @@ import javascript
1414
import DataFlow::PathGraph
1515
import advanced_security.javascript.frameworks.cap.CAPCqlInjectionQuery
1616

17-
DataFlow::Node getQueryOfSink(DataFlow::Node sink) {
18-
exists(CqlRunMethodCall cqlRunMethodCall |
19-
sink = cqlRunMethodCall.(CqlRunMethodCall).getAQueryParameter() and
20-
result = sink
21-
)
22-
or
23-
exists(CqlShortcutMethodCallWithStringConcat shortcutCall |
24-
sink = shortcutCall.(CqlQueryRunnerCall).getAQueryParameter() and
25-
result = shortcutCall
26-
)
27-
or
28-
exists(AwaitExpr await, CqlClauseWithStringConcatParameter cqlClauseWithStringConcat |
29-
sink = await.flow() and
30-
await.getOperand() = cqlClauseWithStringConcat.(CqlClause).asExpr() and
31-
result = cqlClauseWithStringConcat.(CqlClause).flow()
32-
)
33-
}
34-
3517
from CqlInjectionConfiguration sql, DataFlow::PathNode source, DataFlow::PathNode sink
3618
where sql.hasFlowPath(source, sink)
37-
select getQueryOfSink(sink.getNode()), source, sink, "This CQL query depends on a $@.",
38-
source.getNode(), "user-provided value"
19+
select sink.getNode().(CqlInjectionSink).getQuery(), source, sink,
20+
"This CQL query depends on a $@.", source.getNode(), "user-provided value"

javascript/frameworks/cap/test/queries/cqlinjection/cqlinjection.expected

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
WARNING: module 'PathGraph' has been deprecated and may be removed in future (CqlInjection.ql:14,8-27)
2-
WARNING: type 'PathNode' has been deprecated and may be removed in future (CqlInjection.ql:35,37-55)
3-
WARNING: type 'PathNode' has been deprecated and may be removed in future (CqlInjection.ql:35,64-82)
2+
WARNING: type 'PathNode' has been deprecated and may be removed in future (CqlInjection.ql:17,37-55)
3+
WARNING: type 'PathNode' has been deprecated and may be removed in future (CqlInjection.ql:17,64-82)
44
nodes
55
| srv/service1.js:6:33:6:35 | req |
66
| srv/service1.js:6:33:6:35 | req |

0 commit comments

Comments
 (0)