Skip to content

Commit

Permalink
Shared: Add support for provenance pretty-printing as a qltest postpr…
Browse files Browse the repository at this point in the history
…ocess step.
  • Loading branch information
aschackmull committed Jul 18, 2024
1 parent a9bf17e commit 884eff6
Show file tree
Hide file tree
Showing 6 changed files with 95 additions and 36 deletions.
18 changes: 18 additions & 0 deletions java/ql/test/TestUtilities/ProvenancePathGraph.ql
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/**
* @kind test-postprocess
*/

import codeql.dataflow.test.ProvenancePathGraph
import semmle.code.java.dataflow.ExternalFlow

external predicate queryResults(string relation, int row, int column, string data);

external predicate queryRelations(string relation);

query predicate resultRelations(string relation) { queryRelations(relation) }

module Res = TranslateProvenanceResults<interpretModelForTest/2, queryResults/4>;

from string relation, int row, int column, string data
where Res::results(relation, row, column, data)
select relation, row, column, data
28 changes: 16 additions & 12 deletions java/ql/test/query-tests/security/CWE-078/ExecTainted.expected
Original file line number Diff line number Diff line change
@@ -1,23 +1,33 @@
#select
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
edges
| Test.java:6:35:6:44 | arg : String | Test.java:7:44:7:69 | ... + ... : String | provenance | |
| Test.java:6:35:6:44 | arg : String | Test.java:10:61:10:73 | ... + ... : String | provenance | |
| Test.java:6:35:6:44 | arg : String | Test.java:16:13:16:25 | ... + ... : String | provenance | |
| Test.java:6:35:6:44 | arg : String | Test.java:22:15:22:27 | ... + ... : String | provenance | |
| Test.java:7:25:7:70 | new ..[] { .. } : String[] [[]] : String | Test.java:7:25:7:70 | new ..[] { .. } | provenance | Sink:MaD:42682 |
| Test.java:7:25:7:70 | new ..[] { .. } : String[] [[]] : String | Test.java:7:25:7:70 | new ..[] { .. } | provenance | Sink:MaD:2 |
| Test.java:7:44:7:69 | ... + ... : String | Test.java:7:25:7:70 | new ..[] { .. } : String[] [[]] : String | provenance | |
| Test.java:10:29:10:74 | {...} : String[] [[]] : String | Test.java:10:29:10:74 | new String[] | provenance | Sink:MaD:42682 |
| Test.java:10:29:10:74 | {...} : String[] [[]] : String | Test.java:10:29:10:74 | new String[] | provenance | Sink:MaD:2 |
| Test.java:10:61:10:73 | ... + ... : String | Test.java:10:29:10:74 | {...} : String[] [[]] : String | provenance | |
| Test.java:16:5:16:7 | cmd [post update] : ArrayList [<element>] : String | Test.java:18:29:18:31 | cmd | provenance | Sink:MaD:42681 |
| Test.java:16:13:16:25 | ... + ... : String | Test.java:16:5:16:7 | cmd [post update] : ArrayList [<element>] : String | provenance | MaD:43744 |
| Test.java:22:5:22:8 | cmd1 [post update] : String[] [[]] : String | Test.java:24:29:24:32 | cmd1 | provenance | Sink:MaD:42682 |
| Test.java:16:5:16:7 | cmd [post update] : ArrayList [<element>] : String | Test.java:18:29:18:31 | cmd | provenance | Sink:MaD:1 |
| Test.java:16:13:16:25 | ... + ... : String | Test.java:16:5:16:7 | cmd [post update] : ArrayList [<element>] : String | provenance | MaD:3 |
| Test.java:22:5:22:8 | cmd1 [post update] : String[] [[]] : String | Test.java:24:29:24:32 | cmd1 | provenance | Sink:MaD:2 |
| Test.java:22:15:22:27 | ... + ... : String | Test.java:22:5:22:8 | cmd1 [post update] : String[] [[]] : String | provenance | |
| Test.java:28:38:28:47 | arg : String | Test.java:29:44:29:64 | ... + ... : String | provenance | |
| Test.java:29:25:29:65 | new ..[] { .. } : String[] [[]] : String | Test.java:29:25:29:65 | new ..[] { .. } | provenance | Sink:MaD:42682 |
| Test.java:29:25:29:65 | new ..[] { .. } : String[] [[]] : String | Test.java:29:25:29:65 | new ..[] { .. } | provenance | Sink:MaD:2 |
| Test.java:29:44:29:64 | ... + ... : String | Test.java:29:25:29:65 | new ..[] { .. } : String[] [[]] : String | provenance | |
| Test.java:57:27:57:39 | args : String[] | Test.java:60:20:60:22 | arg : String | provenance | |
| Test.java:57:27:57:39 | args : String[] | Test.java:61:23:61:25 | arg : String | provenance | |
| Test.java:60:20:60:22 | arg : String | Test.java:6:35:6:44 | arg : String | provenance | |
| Test.java:61:23:61:25 | arg : String | Test.java:28:38:28:47 | arg : String | provenance | |
models
| 1 | Sink: java.lang; ProcessBuilder; false; ProcessBuilder; (List); ; Argument[0]; command-injection; ai-manual |
| 2 | Sink: java.lang; ProcessBuilder; false; ProcessBuilder; (String[]); ; Argument[0]; command-injection; ai-manual |
| 3 | Summary: java.util; Collection; true; add; ; ; Argument[0]; Argument[this].Element; value; manual |
nodes
| Test.java:6:35:6:44 | arg : String | semmle.label | arg : String |
| Test.java:7:25:7:70 | new ..[] { .. } | semmle.label | new ..[] { .. } |
Expand All @@ -40,9 +50,3 @@ nodes
| Test.java:60:20:60:22 | arg : String | semmle.label | arg : String |
| Test.java:61:23:61:25 | arg : String | semmle.label | arg : String |
subpaths
#select
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
3 changes: 2 additions & 1 deletion java/ql/test/query-tests/security/CWE-078/ExecTainted.qlref
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
Security/CWE/CWE-078/ExecTainted.ql
query: Security/CWE/CWE-078/ExecTainted.ql
postprocess: TestUtilities/ProvenancePathGraph.ql
14 changes: 0 additions & 14 deletions java/ql/test/query-tests/security/CWE-311/CWE-319/HttpsUrls.ql

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
query: Security/CWE/CWE-319/HttpsUrls.ql
postprocess: TestUtilities/ProvenancePathGraph.ql
66 changes: 57 additions & 9 deletions shared/dataflow/codeql/dataflow/test/ProvenancePathGraph.qll
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ module;

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

signature predicate queryResultsSig(string relation, int row, int column, string data);

signature class PathNodeSig {
string toString();
}
Expand All @@ -28,14 +30,14 @@ signature module PathGraphSig<PathNodeSig PathNode> {
predicate subpaths(PathNode arg, PathNode par, PathNode ret, PathNode out);
}

/** Transforms a `PathGraph` by printing the provenance information. */
module ShowProvenance<
interpretModelForTestSig/2 interpretModelForTest, PathNodeSig PathNode,
PathGraphSig<PathNode> PathGraph>
private signature predicate provenanceSig(string model);

private module TranslateModels<
interpretModelForTestSig/2 interpretModelForTest, provenanceSig/1 provenance>
{
private predicate madIds(string madId) {
exists(string model |
PathGraph::edges(_, _, _, model) and
provenance(model) and
model.regexpFind("(?<=MaD:)[0-9]*", _, _) = madId
)
}
Expand All @@ -44,14 +46,15 @@ module ShowProvenance<
madId = rank[r](string madId0 | madIds(madId0) | madId0 order by madId0.toInt())
}

query predicate models(int r, string model) {
/** Lists the renumbered and pretty-printed models used in the edges relation. */
predicate models(int r, string model) {
exists(QlBuiltins::ExtensionId madId |
rankedMadIds(madId.toString(), r) and interpretModelForTest(madId, model)
)
}

private predicate translateModelsPart(string model1, string model2, int i) {
PathGraph::edges(_, _, _, model1) and
provenance(model1) and
exists(string s | model1.splitAt("MaD:", i) = s |
model2 = s and i = 0
or
Expand All @@ -65,21 +68,66 @@ module ShowProvenance<
)
}

private predicate translateModels(string model1, string model2) {
predicate translateModels(string model1, string model2) {
exists(int i |
translateModelsPart(model1, model2, i) and
not translateModelsPart(model1, _, i + 1)
)
}
}

/** Transforms a `PathGraph` by printing the provenance information. */
module ShowProvenance<
interpretModelForTestSig/2 interpretModelForTest, PathNodeSig PathNode,
PathGraphSig<PathNode> PathGraph>
{
private predicate provenance(string model) { PathGraph::edges(_, _, _, model) }

private module Models = TranslateModels<interpretModelForTest/2, provenance/1>;

query predicate models(int r, string model) { Models::models(r, model) }

query predicate edges(PathNode a, PathNode b, string key, string val) {
exists(string model |
PathGraph::edges(a, b, key, model) and
translateModels(model, val)
Models::translateModels(model, val)
)
}

query predicate nodes = PathGraph::nodes/3;

query predicate subpaths = PathGraph::subpaths/4;
}

/** Transforms a `PathGraph` by printing the provenance information. */
module TranslateProvenanceResults<
interpretModelForTestSig/2 interpretModelForTest, queryResultsSig/4 queryResults>
{
private int provenanceColumn() { result = 5 }

private predicate provenance(string model) { queryResults("edges", _, provenanceColumn(), model) }

private module Models = TranslateModels<interpretModelForTest/2, provenance/1>;

predicate results(string relation, int row, int column, string data) {
queryResults(relation, row, column, data) and
(relation != "edges" or column != provenanceColumn())
or
exists(string model |
relation = "edges" and
column = provenanceColumn() and
queryResults(relation, row, column, model) and
Models::translateModels(model, data)
)
or
exists(int r, string model |
Models::models(r, model) and
relation = "models" and
row = r
|
column = 0 and data = r.toString()
or
column = 1 and data = model
)
}
}

0 comments on commit 884eff6

Please sign in to comment.