Skip to content

Commit 89522d0

Browse files
committed
Cover all cases in the current CQL injection test
1 parent c5c9740 commit 89522d0

File tree

4 files changed

+80
-36
lines changed

4 files changed

+80
-36
lines changed

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

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,14 +66,48 @@ class CqlInjectionConfiguration extends TaintTracking::Configuration {
6666
override predicate isSanitizer(DataFlow::Node node) { node instanceof SqlInjection::Sanitizer }
6767

6868
override predicate isAdditionalTaintStep(DataFlow::Node start, DataFlow::Node end) {
69+
/*
70+
* 1.
71+
*/
72+
6973
exists(CqlClauseParserCallWithStringConcat cqlParseCallWithStringConcat |
7074
start = cqlParseCallWithStringConcat.(CqlClauseParserCall).getAnArgument() and
7175
end = cqlParseCallWithStringConcat
7276
)
7377
or
78+
/*
79+
* 2. Jump from a query parameter to the CQL query clause itself. e.g. Given below code:
80+
*
81+
* ``` javascript
82+
* await SELECT.from(Service1Entity).where("ID=" + id);
83+
* ```
84+
*
85+
* This step jumps from `id` in the call to `where` to the entire SELECT clause.
86+
*/
87+
7488
exists(CqlClause cqlClause |
7589
start = cqlClause.getArgument().flow() and
7690
end = cqlClause.flow()
7791
)
92+
or
93+
/*
94+
* 3. In case of INSERT and UPSERT, jump from an object write to a query parameter to the argument itself.
95+
* e.g. Given below code:
96+
*
97+
* ``` javascript
98+
* await INSERT.into(Service1Entity).entries({ id: "" + id });
99+
* ```
100+
*
101+
* This step jumps from `id` in the property value expression to the enclosing object `{ id: "" + id }`.
102+
* This in conjunction with the above step 2 will make the taint tracker jump from `id` to the entire
103+
* INSERT clause.
104+
*/
105+
106+
exists(CqlClause cqlClause, PropWrite propWrite |
107+
(cqlClause instanceof CqlInsertClause or cqlClause instanceof CqlUpsertClause) and
108+
cqlClause.getArgument().flow() = propWrite.getBase() and
109+
start = propWrite.getRhs() and
110+
end = propWrite.getBase()
111+
)
78112
}
79113
}

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

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,18 @@ import advanced_security.javascript.frameworks.cap.CDS
88
*/
99
class CqlQueryBase extends VarRef {
1010
CqlQueryBase() {
11-
exists(string name |
12-
this.getName() = name and
13-
name in ["SELECT", "INSERT", "DELETE", "UPDATE", "UPSERT"] and
14-
(
15-
/* Made available as a global variable */
16-
exists(GlobalVariable queryBase | this = queryBase.getAReference())
17-
or
18-
/* Imported from `cds.ql` */
19-
exists(CdsFacade cds |
20-
cds.getMember("ql").getMember(name).getAValueReachableFromSource().asExpr() = this
11+
exists(VarRef varRef | this = varRef |
12+
exists(string name |
13+
varRef.getName() = name and
14+
name in ["SELECT", "INSERT", "DELETE", "UPDATE", "UPSERT"] and
15+
(
16+
/* Made available as a global variable */
17+
exists(GlobalVariable queryBase | this = queryBase.getAReference())
18+
or
19+
/* Imported from `cds.ql` */
20+
exists(CdsFacade cds |
21+
cds.getMember("ql").getMember(name).getAValueReachableFromSource().asExpr() = this
22+
)
2123
)
2224
)
2325
)
@@ -107,6 +109,8 @@ class CqlClause extends TCqlClause {
107109

108110
CallExpr asShortcutCall() { this = TShortcutCall(result) }
109111

112+
predicate isMethodCall() { this = TMethodCall(_) }
113+
110114
Node flow() { result = this.asExpr().flow() }
111115

112116
Expr asExpr() {

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

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
WARNING: module 'PathGraph' has been deprecated and may be removed in future (CqlInjection.ql:14,8-27)
2-
WARNING: type 'Configuration' has been deprecated and may be removed in future (CqlInjection.ql:19,33-61)
3-
WARNING: type 'PathNode' has been deprecated and may be removed in future (CqlInjection.ql:46,29-47)
4-
WARNING: type 'PathNode' has been deprecated and may be removed in future (CqlInjection.ql:46,56-74)
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)
54
nodes
65
| cqlinjection.js:7:34:7:36 | req |
76
| cqlinjection.js:7:34:7:36 | req |
@@ -16,7 +15,8 @@ nodes
1615
| cqlinjection.js:12:50:12:53 | book |
1716
| cqlinjection.js:13:36:13:40 | query |
1817
| cqlinjection.js:13:36:13:40 | query |
19-
| cqlinjection.js:15:27:15:64 | SELECT. ... book}`) |
18+
| cqlinjection.js:15:21:15:64 | await S ... book}`) |
19+
| cqlinjection.js:15:21:15:64 | await S ... book}`) |
2020
| cqlinjection.js:15:27:15:64 | SELECT. ... book}`) |
2121
| cqlinjection.js:15:52:15:63 | `ID=${book}` |
2222
| cqlinjection.js:15:58:15:61 | book |
@@ -26,7 +26,8 @@ nodes
2626
| cqlinjection.js:17:53:17:56 | book |
2727
| cqlinjection.js:18:37:18:42 | query2 |
2828
| cqlinjection.js:18:37:18:42 | query2 |
29-
| cqlinjection.js:20:27:20:64 | SELECT. ... + book) |
29+
| cqlinjection.js:20:21:20:64 | await S ... + book) |
30+
| cqlinjection.js:20:21:20:64 | await S ... + book) |
3031
| cqlinjection.js:20:27:20:64 | SELECT. ... + book) |
3132
| cqlinjection.js:20:52:20:63 | 'ID=' + book |
3233
| cqlinjection.js:20:60:20:63 | book |
@@ -59,15 +60,17 @@ edges
5960
| cqlinjection.js:12:19:12:56 | SELECT. ... book}`) | cqlinjection.js:12:11:12:56 | query |
6061
| cqlinjection.js:12:44:12:55 | `ID=${book}` | cqlinjection.js:12:19:12:56 | SELECT. ... book}`) |
6162
| cqlinjection.js:12:50:12:53 | book | cqlinjection.js:12:44:12:55 | `ID=${book}` |
62-
| cqlinjection.js:15:52:15:63 | `ID=${book}` | cqlinjection.js:15:27:15:64 | SELECT. ... book}`) |
63+
| cqlinjection.js:15:27:15:64 | SELECT. ... book}`) | cqlinjection.js:15:21:15:64 | await S ... book}`) |
64+
| cqlinjection.js:15:27:15:64 | SELECT. ... book}`) | cqlinjection.js:15:21:15:64 | await S ... book}`) |
6365
| cqlinjection.js:15:52:15:63 | `ID=${book}` | cqlinjection.js:15:27:15:64 | SELECT. ... book}`) |
6466
| cqlinjection.js:15:58:15:61 | book | cqlinjection.js:15:52:15:63 | `ID=${book}` |
6567
| cqlinjection.js:17:11:17:57 | query2 | cqlinjection.js:18:37:18:42 | query2 |
6668
| cqlinjection.js:17:11:17:57 | query2 | cqlinjection.js:18:37:18:42 | query2 |
6769
| cqlinjection.js:17:20:17:57 | SELECT. ... + book) | cqlinjection.js:17:11:17:57 | query2 |
6870
| cqlinjection.js:17:45:17:56 | 'ID=' + book | cqlinjection.js:17:20:17:57 | SELECT. ... + book) |
6971
| cqlinjection.js:17:53:17:56 | book | cqlinjection.js:17:45:17:56 | 'ID=' + book |
70-
| cqlinjection.js:20:52:20:63 | 'ID=' + book | cqlinjection.js:20:27:20:64 | SELECT. ... + book) |
72+
| cqlinjection.js:20:27:20:64 | SELECT. ... + book) | cqlinjection.js:20:21:20:64 | await S ... + book) |
73+
| cqlinjection.js:20:27:20:64 | SELECT. ... + book) | cqlinjection.js:20:21:20:64 | await S ... + book) |
7174
| cqlinjection.js:20:52:20:63 | 'ID=' + book | cqlinjection.js:20:27:20:64 | SELECT. ... + book) |
7275
| cqlinjection.js:20:60:20:63 | book | cqlinjection.js:20:52:20:63 | 'ID=' + book |
7376
| cqlinjection.js:27:11:27:62 | cqn | cqlinjection.js:28:39:28:41 | cqn |
@@ -80,9 +83,9 @@ edges
8083
| cqlinjection.js:30:32:30:59 | `SELECT ... + book | cqlinjection.js:30:18:30:60 | cds.par ... + book) |
8184
| cqlinjection.js:30:56:30:59 | book | cqlinjection.js:30:32:30:59 | `SELECT ... + book |
8285
#select
83-
| cqlinjection.js:13:36:13:40 | query | cqlinjection.js:7:34:7:36 | req | cqlinjection.js:13:36:13:40 | query | This query depends on a $@. | cqlinjection.js:7:34:7:36 | req | user-provided value |
84-
| cqlinjection.js:15:27:15:64 | SELECT. ... book}`) | cqlinjection.js:7:34:7:36 | req | cqlinjection.js:15:27:15:64 | SELECT. ... book}`) | This query depends on a $@. | cqlinjection.js:7:34:7:36 | req | user-provided value |
85-
| cqlinjection.js:18:37:18:42 | query2 | cqlinjection.js:7:34:7:36 | req | cqlinjection.js:18:37:18:42 | query2 | This query depends on a $@. | cqlinjection.js:7:34:7:36 | req | user-provided value |
86-
| cqlinjection.js:20:27:20:64 | SELECT. ... + book) | cqlinjection.js:7:34:7:36 | req | cqlinjection.js:20:27:20:64 | SELECT. ... + book) | This query depends on a $@. | cqlinjection.js:7:34:7:36 | req | user-provided value |
87-
| cqlinjection.js:28:39:28:41 | cqn | cqlinjection.js:7:34:7:36 | req | cqlinjection.js:28:39:28:41 | cqn | This query depends on a $@. | cqlinjection.js:7:34:7:36 | req | user-provided value |
88-
| cqlinjection.js:31:39:31:42 | cqn1 | cqlinjection.js:7:34:7:36 | req | cqlinjection.js:31:39:31:42 | cqn1 | This query depends on a $@. | cqlinjection.js:7:34:7:36 | req | user-provided value |
86+
| cqlinjection.js:13:36:13:40 | query | cqlinjection.js:7:34:7:36 | req | cqlinjection.js:13:36:13:40 | query | This CQL query depends on a $@. | cqlinjection.js:7:34:7:36 | req | user-provided value |
87+
| cqlinjection.js:15:21:15:64 | await S ... book}`) | cqlinjection.js:7:34:7:36 | req | cqlinjection.js:15:21:15:64 | await S ... book}`) | This CQL query depends on a $@. | cqlinjection.js:7:34:7:36 | req | user-provided value |
88+
| cqlinjection.js:18:37:18:42 | query2 | cqlinjection.js:7:34:7:36 | req | cqlinjection.js:18:37:18:42 | query2 | This CQL query depends on a $@. | cqlinjection.js:7:34:7:36 | req | user-provided value |
89+
| cqlinjection.js:20:21:20:64 | await S ... + book) | cqlinjection.js:7:34:7:36 | req | cqlinjection.js:20:21:20:64 | await S ... + book) | This CQL query depends on a $@. | cqlinjection.js:7:34:7:36 | req | user-provided value |
90+
| cqlinjection.js:28:39:28:41 | cqn | cqlinjection.js:7:34:7:36 | req | cqlinjection.js:28:39:28:41 | cqn | This CQL query depends on a $@. | cqlinjection.js:7:34:7:36 | req | user-provided value |
91+
| cqlinjection.js:31:39:31:42 | cqn1 | cqlinjection.js:7:34:7:36 | req | cqlinjection.js:31:39:31:42 | cqn1 | This CQL query depends on a $@. | cqlinjection.js:7:34:7:36 | req | user-provided value |

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

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
WARNING: module 'PathGraph' has been deprecated and may be removed in future (CqlInjection.ql:14,8-27)
2-
WARNING: type 'Configuration' has been deprecated and may be removed in future (CqlInjection.ql:19,33-61)
3-
WARNING: type 'PathNode' has been deprecated and may be removed in future (CqlInjection.ql:46,29-47)
4-
WARNING: type 'PathNode' has been deprecated and may be removed in future (CqlInjection.ql:46,56-74)
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)
54
nodes
65
| cqlinjection.js:7:34:7:36 | req |
76
| cqlinjection.js:7:34:7:36 | req |
@@ -16,7 +15,8 @@ nodes
1615
| cqlinjection.js:12:50:12:53 | book |
1716
| cqlinjection.js:13:36:13:40 | query |
1817
| cqlinjection.js:13:36:13:40 | query |
19-
| cqlinjection.js:15:27:15:64 | SELECT. ... book}`) |
18+
| cqlinjection.js:15:21:15:64 | await S ... book}`) |
19+
| cqlinjection.js:15:21:15:64 | await S ... book}`) |
2020
| cqlinjection.js:15:27:15:64 | SELECT. ... book}`) |
2121
| cqlinjection.js:15:52:15:63 | `ID=${book}` |
2222
| cqlinjection.js:15:58:15:61 | book |
@@ -26,7 +26,8 @@ nodes
2626
| cqlinjection.js:17:53:17:56 | book |
2727
| cqlinjection.js:18:37:18:42 | query2 |
2828
| cqlinjection.js:18:37:18:42 | query2 |
29-
| cqlinjection.js:20:27:20:64 | SELECT. ... + book) |
29+
| cqlinjection.js:20:21:20:64 | await S ... + book) |
30+
| cqlinjection.js:20:21:20:64 | await S ... + book) |
3031
| cqlinjection.js:20:27:20:64 | SELECT. ... + book) |
3132
| cqlinjection.js:20:52:20:63 | 'ID=' + book |
3233
| cqlinjection.js:20:60:20:63 | book |
@@ -59,15 +60,17 @@ edges
5960
| cqlinjection.js:12:19:12:56 | SELECT. ... book}`) | cqlinjection.js:12:11:12:56 | query |
6061
| cqlinjection.js:12:44:12:55 | `ID=${book}` | cqlinjection.js:12:19:12:56 | SELECT. ... book}`) |
6162
| cqlinjection.js:12:50:12:53 | book | cqlinjection.js:12:44:12:55 | `ID=${book}` |
62-
| cqlinjection.js:15:52:15:63 | `ID=${book}` | cqlinjection.js:15:27:15:64 | SELECT. ... book}`) |
63+
| cqlinjection.js:15:27:15:64 | SELECT. ... book}`) | cqlinjection.js:15:21:15:64 | await S ... book}`) |
64+
| cqlinjection.js:15:27:15:64 | SELECT. ... book}`) | cqlinjection.js:15:21:15:64 | await S ... book}`) |
6365
| cqlinjection.js:15:52:15:63 | `ID=${book}` | cqlinjection.js:15:27:15:64 | SELECT. ... book}`) |
6466
| cqlinjection.js:15:58:15:61 | book | cqlinjection.js:15:52:15:63 | `ID=${book}` |
6567
| cqlinjection.js:17:11:17:57 | query2 | cqlinjection.js:18:37:18:42 | query2 |
6668
| cqlinjection.js:17:11:17:57 | query2 | cqlinjection.js:18:37:18:42 | query2 |
6769
| cqlinjection.js:17:20:17:57 | SELECT. ... + book) | cqlinjection.js:17:11:17:57 | query2 |
6870
| cqlinjection.js:17:45:17:56 | 'ID=' + book | cqlinjection.js:17:20:17:57 | SELECT. ... + book) |
6971
| cqlinjection.js:17:53:17:56 | book | cqlinjection.js:17:45:17:56 | 'ID=' + book |
70-
| cqlinjection.js:20:52:20:63 | 'ID=' + book | cqlinjection.js:20:27:20:64 | SELECT. ... + book) |
72+
| cqlinjection.js:20:27:20:64 | SELECT. ... + book) | cqlinjection.js:20:21:20:64 | await S ... + book) |
73+
| cqlinjection.js:20:27:20:64 | SELECT. ... + book) | cqlinjection.js:20:21:20:64 | await S ... + book) |
7174
| cqlinjection.js:20:52:20:63 | 'ID=' + book | cqlinjection.js:20:27:20:64 | SELECT. ... + book) |
7275
| cqlinjection.js:20:60:20:63 | book | cqlinjection.js:20:52:20:63 | 'ID=' + book |
7376
| cqlinjection.js:27:11:27:62 | cqn | cqlinjection.js:28:39:28:41 | cqn |
@@ -80,9 +83,9 @@ edges
8083
| cqlinjection.js:30:32:30:59 | `SELECT ... + book | cqlinjection.js:30:18:30:60 | cds.par ... + book) |
8184
| cqlinjection.js:30:56:30:59 | book | cqlinjection.js:30:32:30:59 | `SELECT ... + book |
8285
#select
83-
| cqlinjection.js:13:36:13:40 | query | cqlinjection.js:7:34:7:36 | req | cqlinjection.js:13:36:13:40 | query | This query depends on a $@. | cqlinjection.js:7:34:7:36 | req | user-provided value |
84-
| cqlinjection.js:15:27:15:64 | SELECT. ... book}`) | cqlinjection.js:7:34:7:36 | req | cqlinjection.js:15:27:15:64 | SELECT. ... book}`) | This query depends on a $@. | cqlinjection.js:7:34:7:36 | req | user-provided value |
85-
| cqlinjection.js:18:37:18:42 | query2 | cqlinjection.js:7:34:7:36 | req | cqlinjection.js:18:37:18:42 | query2 | This query depends on a $@. | cqlinjection.js:7:34:7:36 | req | user-provided value |
86-
| cqlinjection.js:20:27:20:64 | SELECT. ... + book) | cqlinjection.js:7:34:7:36 | req | cqlinjection.js:20:27:20:64 | SELECT. ... + book) | This query depends on a $@. | cqlinjection.js:7:34:7:36 | req | user-provided value |
87-
| cqlinjection.js:28:39:28:41 | cqn | cqlinjection.js:7:34:7:36 | req | cqlinjection.js:28:39:28:41 | cqn | This query depends on a $@. | cqlinjection.js:7:34:7:36 | req | user-provided value |
88-
| cqlinjection.js:31:39:31:42 | cqn1 | cqlinjection.js:7:34:7:36 | req | cqlinjection.js:31:39:31:42 | cqn1 | This query depends on a $@. | cqlinjection.js:7:34:7:36 | req | user-provided value |
86+
| cqlinjection.js:13:36:13:40 | query | cqlinjection.js:7:34:7:36 | req | cqlinjection.js:13:36:13:40 | query | This CQL query depends on a $@. | cqlinjection.js:7:34:7:36 | req | user-provided value |
87+
| cqlinjection.js:15:21:15:64 | await S ... book}`) | cqlinjection.js:7:34:7:36 | req | cqlinjection.js:15:21:15:64 | await S ... book}`) | This CQL query depends on a $@. | cqlinjection.js:7:34:7:36 | req | user-provided value |
88+
| cqlinjection.js:18:37:18:42 | query2 | cqlinjection.js:7:34:7:36 | req | cqlinjection.js:18:37:18:42 | query2 | This CQL query depends on a $@. | cqlinjection.js:7:34:7:36 | req | user-provided value |
89+
| cqlinjection.js:20:21:20:64 | await S ... + book) | cqlinjection.js:7:34:7:36 | req | cqlinjection.js:20:21:20:64 | await S ... + book) | This CQL query depends on a $@. | cqlinjection.js:7:34:7:36 | req | user-provided value |
90+
| cqlinjection.js:28:39:28:41 | cqn | cqlinjection.js:7:34:7:36 | req | cqlinjection.js:28:39:28:41 | cqn | This CQL query depends on a $@. | cqlinjection.js:7:34:7:36 | req | user-provided value |
91+
| cqlinjection.js:31:39:31:42 | cqn1 | cqlinjection.js:7:34:7:36 | req | cqlinjection.js:31:39:31:42 | cqn1 | This CQL query depends on a $@. | cqlinjection.js:7:34:7:36 | req | user-provided value |

0 commit comments

Comments
 (0)