Skip to content

Commit 822f8b0

Browse files
authored
Merge pull request #17011 from aschackmull/dataflow/provenance-postprocess-qltest
Shared: Add support for provenance pretty-printing as a qltest postprocess step.
2 parents 52020f7 + c051d33 commit 822f8b0

File tree

6 files changed

+95
-36
lines changed

6 files changed

+95
-36
lines changed
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
/**
2+
* @kind test-postprocess
3+
*/
4+
5+
import codeql.dataflow.test.ProvenancePathGraph
6+
import semmle.code.java.dataflow.ExternalFlow
7+
8+
external predicate queryResults(string relation, int row, int column, string data);
9+
10+
external predicate queryRelations(string relation);
11+
12+
query predicate resultRelations(string relation) { queryRelations(relation) }
13+
14+
module Res = TranslateProvenanceResults<interpretModelForTest/2, queryResults/4>;
15+
16+
from string relation, int row, int column, string data
17+
where Res::results(relation, row, column, data)
18+
select relation, row, column, data

java/ql/test/query-tests/security/CWE-078/ExecTainted.expected

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,33 @@
1+
#select
2+
| Test.java:7:44:7:69 | ... + ... | Test.java:57:27:57:39 | args : String[] | Test.java:7:25:7:70 | new ..[] { .. } | This command line depends on a $@. | Test.java:57:27:57:39 | args | user-provided value |
3+
| Test.java:10:29:10:74 | new String[] | Test.java:57:27:57:39 | args : String[] | Test.java:10:29:10:74 | new String[] | This command line depends on a $@. | Test.java:57:27:57:39 | args | user-provided value |
4+
| Test.java:18:29:18:31 | cmd | Test.java:57:27:57:39 | args : String[] | Test.java:18:29:18:31 | cmd | This command line depends on a $@. | Test.java:57:27:57:39 | args | user-provided value |
5+
| Test.java:24:29:24:32 | cmd1 | Test.java:57:27:57:39 | args : String[] | Test.java:24:29:24:32 | cmd1 | This command line depends on a $@. | Test.java:57:27:57:39 | args | user-provided value |
6+
| Test.java:29:44:29:64 | ... + ... | Test.java:57:27:57:39 | args : String[] | Test.java:29:25:29:65 | new ..[] { .. } | This command line depends on a $@. | Test.java:57:27:57:39 | args | user-provided value |
17
edges
28
| Test.java:6:35:6:44 | arg : String | Test.java:7:44:7:69 | ... + ... : String | provenance | |
39
| Test.java:6:35:6:44 | arg : String | Test.java:10:61:10:73 | ... + ... : String | provenance | |
410
| Test.java:6:35:6:44 | arg : String | Test.java:16:13:16:25 | ... + ... : String | provenance | |
511
| Test.java:6:35:6:44 | arg : String | Test.java:22:15:22:27 | ... + ... : String | provenance | |
6-
| Test.java:7:25:7:70 | new ..[] { .. } : String[] [[]] : String | Test.java:7:25:7:70 | new ..[] { .. } | provenance | Sink:MaD:42682 |
12+
| Test.java:7:25:7:70 | new ..[] { .. } : String[] [[]] : String | Test.java:7:25:7:70 | new ..[] { .. } | provenance | Sink:MaD:2 |
713
| Test.java:7:44:7:69 | ... + ... : String | Test.java:7:25:7:70 | new ..[] { .. } : String[] [[]] : String | provenance | |
8-
| Test.java:10:29:10:74 | {...} : String[] [[]] : String | Test.java:10:29:10:74 | new String[] | provenance | Sink:MaD:42682 |
14+
| Test.java:10:29:10:74 | {...} : String[] [[]] : String | Test.java:10:29:10:74 | new String[] | provenance | Sink:MaD:2 |
915
| Test.java:10:61:10:73 | ... + ... : String | Test.java:10:29:10:74 | {...} : String[] [[]] : String | provenance | |
10-
| Test.java:16:5:16:7 | cmd [post update] : ArrayList [<element>] : String | Test.java:18:29:18:31 | cmd | provenance | Sink:MaD:42681 |
11-
| Test.java:16:13:16:25 | ... + ... : String | Test.java:16:5:16:7 | cmd [post update] : ArrayList [<element>] : String | provenance | MaD:43744 |
12-
| Test.java:22:5:22:8 | cmd1 [post update] : String[] [[]] : String | Test.java:24:29:24:32 | cmd1 | provenance | Sink:MaD:42682 |
16+
| Test.java:16:5:16:7 | cmd [post update] : ArrayList [<element>] : String | Test.java:18:29:18:31 | cmd | provenance | Sink:MaD:1 |
17+
| Test.java:16:13:16:25 | ... + ... : String | Test.java:16:5:16:7 | cmd [post update] : ArrayList [<element>] : String | provenance | MaD:3 |
18+
| Test.java:22:5:22:8 | cmd1 [post update] : String[] [[]] : String | Test.java:24:29:24:32 | cmd1 | provenance | Sink:MaD:2 |
1319
| Test.java:22:15:22:27 | ... + ... : String | Test.java:22:5:22:8 | cmd1 [post update] : String[] [[]] : String | provenance | |
1420
| Test.java:28:38:28:47 | arg : String | Test.java:29:44:29:64 | ... + ... : String | provenance | |
15-
| Test.java:29:25:29:65 | new ..[] { .. } : String[] [[]] : String | Test.java:29:25:29:65 | new ..[] { .. } | provenance | Sink:MaD:42682 |
21+
| Test.java:29:25:29:65 | new ..[] { .. } : String[] [[]] : String | Test.java:29:25:29:65 | new ..[] { .. } | provenance | Sink:MaD:2 |
1622
| Test.java:29:44:29:64 | ... + ... : String | Test.java:29:25:29:65 | new ..[] { .. } : String[] [[]] : String | provenance | |
1723
| Test.java:57:27:57:39 | args : String[] | Test.java:60:20:60:22 | arg : String | provenance | |
1824
| Test.java:57:27:57:39 | args : String[] | Test.java:61:23:61:25 | arg : String | provenance | |
1925
| Test.java:60:20:60:22 | arg : String | Test.java:6:35:6:44 | arg : String | provenance | |
2026
| Test.java:61:23:61:25 | arg : String | Test.java:28:38:28:47 | arg : String | provenance | |
27+
models
28+
| 1 | Sink: java.lang; ProcessBuilder; false; ProcessBuilder; (List); ; Argument[0]; command-injection; ai-manual |
29+
| 2 | Sink: java.lang; ProcessBuilder; false; ProcessBuilder; (String[]); ; Argument[0]; command-injection; ai-manual |
30+
| 3 | Summary: java.util; Collection; true; add; ; ; Argument[0]; Argument[this].Element; value; manual |
2131
nodes
2232
| Test.java:6:35:6:44 | arg : String | semmle.label | arg : String |
2333
| Test.java:7:25:7:70 | new ..[] { .. } | semmle.label | new ..[] { .. } |
@@ -40,9 +50,3 @@ nodes
4050
| Test.java:60:20:60:22 | arg : String | semmle.label | arg : String |
4151
| Test.java:61:23:61:25 | arg : String | semmle.label | arg : String |
4252
subpaths
43-
#select
44-
| Test.java:7:44:7:69 | ... + ... | Test.java:57:27:57:39 | args : String[] | Test.java:7:25:7:70 | new ..[] { .. } | This command line depends on a $@. | Test.java:57:27:57:39 | args | user-provided value |
45-
| Test.java:10:29:10:74 | new String[] | Test.java:57:27:57:39 | args : String[] | Test.java:10:29:10:74 | new String[] | This command line depends on a $@. | Test.java:57:27:57:39 | args | user-provided value |
46-
| Test.java:18:29:18:31 | cmd | Test.java:57:27:57:39 | args : String[] | Test.java:18:29:18:31 | cmd | This command line depends on a $@. | Test.java:57:27:57:39 | args | user-provided value |
47-
| Test.java:24:29:24:32 | cmd1 | Test.java:57:27:57:39 | args : String[] | Test.java:24:29:24:32 | cmd1 | This command line depends on a $@. | Test.java:57:27:57:39 | args | user-provided value |
48-
| Test.java:29:44:29:64 | ... + ... | Test.java:57:27:57:39 | args : String[] | Test.java:29:25:29:65 | new ..[] { .. } | This command line depends on a $@. | Test.java:57:27:57:39 | args | user-provided value |
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
1-
Security/CWE/CWE-078/ExecTainted.ql
1+
query: Security/CWE/CWE-078/ExecTainted.ql
2+
postprocess: TestUtilities/PrettyPrintModels.ql

java/ql/test/query-tests/security/CWE-311/CWE-319/HttpsUrls.ql

Lines changed: 0 additions & 14 deletions
This file was deleted.
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
query: Security/CWE/CWE-319/HttpsUrls.ql
2+
postprocess: TestUtilities/PrettyPrintModels.ql

shared/dataflow/codeql/dataflow/test/ProvenancePathGraph.qll

Lines changed: 57 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ module;
99

1010
signature predicate interpretModelForTestSig(QlBuiltins::ExtensionId madId, string model);
1111

12+
signature predicate queryResultsSig(string relation, int row, int column, string data);
13+
1214
signature class PathNodeSig {
1315
string toString();
1416
}
@@ -28,14 +30,14 @@ signature module PathGraphSig<PathNodeSig PathNode> {
2830
predicate subpaths(PathNode arg, PathNode par, PathNode ret, PathNode out);
2931
}
3032

31-
/** Transforms a `PathGraph` by printing the provenance information. */
32-
module ShowProvenance<
33-
interpretModelForTestSig/2 interpretModelForTest, PathNodeSig PathNode,
34-
PathGraphSig<PathNode> PathGraph>
33+
private signature predicate provenanceSig(string model);
34+
35+
private module TranslateModels<
36+
interpretModelForTestSig/2 interpretModelForTest, provenanceSig/1 provenance>
3537
{
3638
private predicate madIds(string madId) {
3739
exists(string model |
38-
PathGraph::edges(_, _, _, model) and
40+
provenance(model) and
3941
model.regexpFind("(?<=MaD:)[0-9]*", _, _) = madId
4042
)
4143
}
@@ -44,14 +46,15 @@ module ShowProvenance<
4446
madId = rank[r](string madId0 | madIds(madId0) | madId0 order by madId0.toInt())
4547
}
4648

47-
query predicate models(int r, string model) {
49+
/** Lists the renumbered and pretty-printed models used in the edges relation. */
50+
predicate models(int r, string model) {
4851
exists(QlBuiltins::ExtensionId madId |
4952
rankedMadIds(madId.toString(), r) and interpretModelForTest(madId, model)
5053
)
5154
}
5255

5356
private predicate translateModelsPart(string model1, string model2, int i) {
54-
PathGraph::edges(_, _, _, model1) and
57+
provenance(model1) and
5558
exists(string s | model1.splitAt("MaD:", i) = s |
5659
model2 = s and i = 0
5760
or
@@ -65,21 +68,66 @@ module ShowProvenance<
6568
)
6669
}
6770

68-
private predicate translateModels(string model1, string model2) {
71+
predicate translateModels(string model1, string model2) {
6972
exists(int i |
7073
translateModelsPart(model1, model2, i) and
7174
not translateModelsPart(model1, _, i + 1)
7275
)
7376
}
77+
}
78+
79+
/** Transforms a `PathGraph` by printing the provenance information. */
80+
module ShowProvenance<
81+
interpretModelForTestSig/2 interpretModelForTest, PathNodeSig PathNode,
82+
PathGraphSig<PathNode> PathGraph>
83+
{
84+
private predicate provenance(string model) { PathGraph::edges(_, _, _, model) }
85+
86+
private module Models = TranslateModels<interpretModelForTest/2, provenance/1>;
87+
88+
query predicate models(int r, string model) { Models::models(r, model) }
7489

7590
query predicate edges(PathNode a, PathNode b, string key, string val) {
7691
exists(string model |
7792
PathGraph::edges(a, b, key, model) and
78-
translateModels(model, val)
93+
Models::translateModels(model, val)
7994
)
8095
}
8196

8297
query predicate nodes = PathGraph::nodes/3;
8398

8499
query predicate subpaths = PathGraph::subpaths/4;
85100
}
101+
102+
/** Transforms a `PathGraph` by printing the provenance information. */
103+
module TranslateProvenanceResults<
104+
interpretModelForTestSig/2 interpretModelForTest, queryResultsSig/4 queryResults>
105+
{
106+
private int provenanceColumn() { result = 5 }
107+
108+
private predicate provenance(string model) { queryResults("edges", _, provenanceColumn(), model) }
109+
110+
private module Models = TranslateModels<interpretModelForTest/2, provenance/1>;
111+
112+
predicate results(string relation, int row, int column, string data) {
113+
queryResults(relation, row, column, data) and
114+
(relation != "edges" or column != provenanceColumn())
115+
or
116+
exists(string model |
117+
relation = "edges" and
118+
column = provenanceColumn() and
119+
queryResults(relation, row, column, model) and
120+
Models::translateModels(model, data)
121+
)
122+
or
123+
exists(int r, string model |
124+
Models::models(r, model) and
125+
relation = "models" and
126+
row = r
127+
|
128+
column = 0 and data = r.toString()
129+
or
130+
column = 1 and data = model
131+
)
132+
}
133+
}

0 commit comments

Comments
 (0)