Skip to content

Commit 424362a

Browse files
committed
Java: Address review comment. Fix dataflow model
1 parent ccfbf55 commit 424362a

File tree

5 files changed

+111
-47
lines changed

5 files changed

+111
-47
lines changed

java/ql/lib/ext/javax.crypto.model.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ extensions:
1818
- ["javax.crypto", "KDF", False, "getInstance", "(String,KDFParameters,Provider)", "", "Argument[0]", "ReturnValue.SyntheticField[javax.crypto.KDF.algorithm]", "value", "manual"]
1919
- ["javax.crypto", "KDF", False, "getInstance", "(String,KDFParameters,String)", "", "Argument[0]", "ReturnValue.SyntheticField[javax.crypto.KDF.algorithm]", "value", "manual"]
2020
- ["javax.crypto", "KDF", True, "getAlgorithm", "()", "", "Argument[this].SyntheticField[javax.crypto.KDF.algorithm]", "ReturnValue", "value", "manual"]
21-
- ["javax.crypto", "KDF", True, "getProvider", "()", "", "Argument[this]", "ReturnValue", "value", "manual"]
21+
- ["javax.crypto", "KDF", True, "getProvider", "()", "", "Argument[this]", "ReturnValue", "taint", "manual"]
2222
- ["javax.crypto", "KDF", True, "deriveKey", "(String,AlgorithmParameterSpec)", "", "Argument[1]", "ReturnValue", "taint", "manual"]
2323
- ["javax.crypto", "KDF", True, "deriveData", "(AlgorithmParameterSpec)", "", "Argument[0]", "ReturnValue", "taint", "manual"]
2424
- ["javax.crypto", "SecretKey", True, "getEncoded", "()", "", "Argument[this]", "ReturnValue", "taint", "manual"]

java/ql/lib/ext/javax.crypto.spec.model.yml

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,19 +8,15 @@ extensions:
88
- ["javax.crypto.spec", "RC2ParameterSpec", True, "RC2ParameterSpec", "", "", "Argument[1]", "Argument[this]", "taint", "manual"]
99
- ["javax.crypto.spec", "RC5ParameterSpec", True, "RC5ParameterSpec", "", "", "Argument[3]", "Argument[this]", "taint", "manual"]
1010
- ["javax.crypto.spec", "HKDFParameterSpec$Builder", True, "addIKM", "(byte[])", "", "Argument[0]", "Argument[this]", "taint", "manual"]
11-
- ["javax.crypto.spec", "HKDFParameterSpec$Builder", True, "addIKM", "(byte[])", "", "Argument[0]", "ReturnValue", "taint", "manual"]
12-
- ["javax.crypto.spec", "HKDFParameterSpec$Builder", True, "addIKM", "(byte[])", "", "Argument[this]", "ReturnValue", "taint", "manual"]
11+
- ["javax.crypto.spec", "HKDFParameterSpec$Builder", True, "addIKM", "(byte[])", "", "Argument[this]", "ReturnValue", "value", "manual"]
1312
- ["javax.crypto.spec", "HKDFParameterSpec$Builder", True, "addIKM", "(SecretKey)", "", "Argument[0]", "Argument[this]", "taint", "manual"]
14-
- ["javax.crypto.spec", "HKDFParameterSpec$Builder", True, "addIKM", "(SecretKey)", "", "Argument[0]", "ReturnValue", "taint", "manual"]
15-
- ["javax.crypto.spec", "HKDFParameterSpec$Builder", True, "addIKM", "(SecretKey)", "", "Argument[this]", "ReturnValue", "taint", "manual"]
13+
- ["javax.crypto.spec", "HKDFParameterSpec$Builder", True, "addIKM", "(SecretKey)", "", "Argument[this]", "ReturnValue", "value", "manual"]
1614
- ["javax.crypto.spec", "HKDFParameterSpec$Builder", True, "addSalt", "(byte[])", "", "Argument[0]", "Argument[this]", "taint", "manual"]
17-
- ["javax.crypto.spec", "HKDFParameterSpec$Builder", True, "addSalt", "(byte[])", "", "Argument[0]", "ReturnValue", "taint", "manual"]
18-
- ["javax.crypto.spec", "HKDFParameterSpec$Builder", True, "addSalt", "(byte[])", "", "Argument[this]", "ReturnValue", "taint", "manual"]
15+
- ["javax.crypto.spec", "HKDFParameterSpec$Builder", True, "addSalt", "(byte[])", "", "Argument[this]", "ReturnValue", "value", "manual"]
1916
- ["javax.crypto.spec", "HKDFParameterSpec$Builder", True, "addSalt", "(SecretKey)", "", "Argument[0]", "Argument[this]", "taint", "manual"]
20-
- ["javax.crypto.spec", "HKDFParameterSpec$Builder", True, "addSalt", "(SecretKey)", "", "Argument[0]", "ReturnValue", "taint", "manual"]
21-
- ["javax.crypto.spec", "HKDFParameterSpec$Builder", True, "addSalt", "(SecretKey)", "", "Argument[this]", "ReturnValue", "taint", "manual"]
17+
- ["javax.crypto.spec", "HKDFParameterSpec$Builder", True, "addSalt", "(SecretKey)", "", "Argument[this]", "ReturnValue", "value", "manual"]
18+
- ["javax.crypto.spec", "HKDFParameterSpec$Builder", True, "thenExpand", "(byte[],int)", "", "Argument[0]", "Argument[this]", "taint", "manual"]
2219
- ["javax.crypto.spec", "HKDFParameterSpec$Builder", True, "thenExpand", "(byte[],int)", "", "Argument[this]", "ReturnValue", "taint", "manual"]
23-
- ["javax.crypto.spec", "HKDFParameterSpec$Builder", True, "thenExpand", "(byte[],int)", "", "Argument[0]", "ReturnValue", "taint", "manual"]
2420
- ["javax.crypto.spec", "HKDFParameterSpec", False, "expandOnly", "(SecretKey,byte[],int)", "", "Argument[0]", "ReturnValue", "taint", "manual"]
2521
- ["javax.crypto.spec", "HKDFParameterSpec", False, "expandOnly", "(SecretKey,byte[],int)", "", "Argument[1]", "ReturnValue", "taint", "manual"]
2622
- ["javax.crypto.spec", "SecretKeySpec", False, "SecretKeySpec", "(byte[],String)", "", "Argument[0]", "Argument[this]", "taint", "manual"]

java/ql/test/library-tests/dataflow/kdf/KDFDataflowTest.java

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,14 @@
22
import javax.crypto.spec.HKDFParameterSpec;
33

44
public class KDFDataflowTest {
5+
public static String source(String label) {
6+
return "tainted";
7+
}
8+
9+
public static void sink(Object o) {}
10+
511
public static void main(String[] args) throws Exception {
6-
String userInput = args[0]; // source
12+
String userInput = source("");
713
byte[] taintedBytes = userInput.getBytes();
814

915
testBuilderPattern(taintedBytes);
@@ -20,7 +26,7 @@ public static void testBuilderPattern(byte[] taintedIKM) throws Exception {
2026

2127
KDF kdf = KDF.getInstance("HKDF-SHA256");
2228
byte[] result = kdf.deriveData(spec);
23-
sink(result); // should flag
29+
sink(result); // $ hasTaintFlow
2430
}
2531

2632
public static void testSeparateBuilder(byte[] taintedIKM) throws Exception {
@@ -30,11 +36,9 @@ public static void testSeparateBuilder(byte[] taintedIKM) throws Exception {
3036

3137
KDF kdf = KDF.getInstance("HKDF-SHA256");
3238
byte[] result = kdf.deriveData(spec);
33-
sink(result); // should flag
39+
sink(result); // $ hasTaintFlow
3440
}
3541

36-
public static void sink(Object o) {}
37-
3842
public static void testKDFWithSalt(byte[] taintedIKM) throws Exception {
3943
HKDFParameterSpec.Builder builder = HKDFParameterSpec.ofExtract();
4044
builder.addIKM(taintedIKM);
@@ -43,7 +47,7 @@ public static void testKDFWithSalt(byte[] taintedIKM) throws Exception {
4347

4448
KDF kdf = KDF.getInstance("HKDF-SHA256");
4549
byte[] result = kdf.deriveData(spec);
46-
sink(result); // should flag
50+
sink(result); // $ hasTaintFlow
4751
}
4852

4953
public static void testStaticParameterSpec(byte[] taintedIKM) throws Exception {
@@ -53,18 +57,18 @@ public static void testStaticParameterSpec(byte[] taintedIKM) throws Exception {
5357

5458
KDF kdf = KDF.getInstance("HKDF-SHA256");
5559
byte[] result = kdf.deriveData(spec);
56-
sink(result); // should flag
60+
sink(result); // $ hasTaintFlow
5761
}
5862

5963
public static void testCleanUsage() throws Exception {
6064
byte[] cleanKeyMaterial = "static-key-material".getBytes();
6165

6266
HKDFParameterSpec.Builder builder = HKDFParameterSpec.ofExtract();
63-
builder.addIKM(cleanKeyMaterial); // clean input
67+
builder.addIKM(cleanKeyMaterial);
6468
HKDFParameterSpec spec = builder.thenExpand("info".getBytes(), 32);
6569

6670
KDF kdf = KDF.getInstance("HKDF-SHA256");
6771
byte[] cleanResult = kdf.deriveData(spec);
68-
sink(cleanResult); // should NOT flag - no taint source
72+
sink(cleanResult); // Safe - no taint
6973
}
7074
}
Lines changed: 89 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,89 @@
1-
| KDFDataflowTest.java:6:28:6:34 | ...[...] | KDFDataflowTest.java:23:14:23:19 | result |
2-
| KDFDataflowTest.java:6:28:6:34 | ...[...] | KDFDataflowTest.java:33:14:33:19 | result |
3-
| KDFDataflowTest.java:6:28:6:34 | ...[...] | KDFDataflowTest.java:46:14:46:19 | result |
4-
| KDFDataflowTest.java:6:28:6:34 | ...[...] | KDFDataflowTest.java:56:14:56:19 | result |
1+
models
2+
| 1 | Summary: java.lang; String; false; getBytes; ; ; Argument[this]; ReturnValue; taint; manual |
3+
| 2 | Summary: javax.crypto.spec; HKDFParameterSpec$Builder; true; addIKM; (byte[]); ; Argument[0]; Argument[this]; taint; manual |
4+
| 3 | Summary: javax.crypto.spec; HKDFParameterSpec$Builder; true; addIKM; (byte[]); ; Argument[this]; ReturnValue; value; manual |
5+
| 4 | Summary: javax.crypto.spec; HKDFParameterSpec$Builder; true; thenExpand; (byte[],int); ; Argument[this]; ReturnValue; taint; manual |
6+
| 5 | Summary: javax.crypto.spec; HKDFParameterSpec; false; expandOnly; (SecretKey,byte[],int); ; Argument[0]; ReturnValue; taint; manual |
7+
| 6 | Summary: javax.crypto.spec; SecretKeySpec; false; SecretKeySpec; (byte[],String); ; Argument[0]; Argument[this]; taint; manual |
8+
| 7 | Summary: javax.crypto; KDF; true; deriveData; (AlgorithmParameterSpec); ; Argument[0]; ReturnValue; taint; manual |
9+
edges
10+
| KDFDataflowTest.java:12:28:12:37 | source(...) : String | KDFDataflowTest.java:13:31:13:39 | userInput : String | provenance | |
11+
| KDFDataflowTest.java:13:31:13:39 | userInput : String | KDFDataflowTest.java:13:31:13:50 | getBytes(...) : byte[] | provenance | MaD:1 |
12+
| KDFDataflowTest.java:13:31:13:50 | getBytes(...) : byte[] | KDFDataflowTest.java:15:28:15:39 | taintedBytes : byte[] | provenance | |
13+
| KDFDataflowTest.java:13:31:13:50 | getBytes(...) : byte[] | KDFDataflowTest.java:16:29:16:40 | taintedBytes : byte[] | provenance | |
14+
| KDFDataflowTest.java:13:31:13:50 | getBytes(...) : byte[] | KDFDataflowTest.java:17:25:17:36 | taintedBytes : byte[] | provenance | |
15+
| KDFDataflowTest.java:13:31:13:50 | getBytes(...) : byte[] | KDFDataflowTest.java:18:33:18:44 | taintedBytes : byte[] | provenance | |
16+
| KDFDataflowTest.java:15:28:15:39 | taintedBytes : byte[] | KDFDataflowTest.java:22:43:22:59 | taintedIKM : byte[] | provenance | |
17+
| KDFDataflowTest.java:16:29:16:40 | taintedBytes : byte[] | KDFDataflowTest.java:32:44:32:60 | taintedIKM : byte[] | provenance | |
18+
| KDFDataflowTest.java:17:25:17:36 | taintedBytes : byte[] | KDFDataflowTest.java:42:40:42:56 | taintedIKM : byte[] | provenance | |
19+
| KDFDataflowTest.java:18:33:18:44 | taintedBytes : byte[] | KDFDataflowTest.java:53:48:53:64 | taintedIKM : byte[] | provenance | |
20+
| KDFDataflowTest.java:22:43:22:59 | taintedIKM : byte[] | KDFDataflowTest.java:24:24:24:33 | taintedIKM : byte[] | provenance | |
21+
| KDFDataflowTest.java:24:9:24:15 | builder [post update] : Builder | KDFDataflowTest.java:25:34:25:40 | builder : Builder | provenance | |
22+
| KDFDataflowTest.java:24:24:24:33 | taintedIKM : byte[] | KDFDataflowTest.java:24:9:24:15 | builder [post update] : Builder | provenance | MaD:2 |
23+
| KDFDataflowTest.java:25:34:25:40 | builder : Builder | KDFDataflowTest.java:25:34:25:74 | thenExpand(...) : ExtractThenExpand | provenance | MaD:4 |
24+
| KDFDataflowTest.java:25:34:25:74 | thenExpand(...) : ExtractThenExpand | KDFDataflowTest.java:28:40:28:43 | spec : ExtractThenExpand | provenance | |
25+
| KDFDataflowTest.java:28:25:28:44 | deriveData(...) : byte[] | KDFDataflowTest.java:29:14:29:19 | result | provenance | |
26+
| KDFDataflowTest.java:28:40:28:43 | spec : ExtractThenExpand | KDFDataflowTest.java:28:25:28:44 | deriveData(...) : byte[] | provenance | MaD:7 |
27+
| KDFDataflowTest.java:32:44:32:60 | taintedIKM : byte[] | KDFDataflowTest.java:34:62:34:71 | taintedIKM : byte[] | provenance | |
28+
| KDFDataflowTest.java:34:46:34:72 | addIKM(...) : Builder | KDFDataflowTest.java:35:34:35:41 | builder2 : Builder | provenance | |
29+
| KDFDataflowTest.java:34:62:34:71 | taintedIKM : byte[] | KDFDataflowTest.java:34:46:34:72 | addIKM(...) : Builder | provenance | MaD:2+MaD:3 |
30+
| KDFDataflowTest.java:35:34:35:41 | builder2 : Builder | KDFDataflowTest.java:35:34:35:75 | thenExpand(...) : ExtractThenExpand | provenance | MaD:4 |
31+
| KDFDataflowTest.java:35:34:35:75 | thenExpand(...) : ExtractThenExpand | KDFDataflowTest.java:38:40:38:43 | spec : ExtractThenExpand | provenance | |
32+
| KDFDataflowTest.java:38:25:38:44 | deriveData(...) : byte[] | KDFDataflowTest.java:39:14:39:19 | result | provenance | |
33+
| KDFDataflowTest.java:38:40:38:43 | spec : ExtractThenExpand | KDFDataflowTest.java:38:25:38:44 | deriveData(...) : byte[] | provenance | MaD:7 |
34+
| KDFDataflowTest.java:42:40:42:56 | taintedIKM : byte[] | KDFDataflowTest.java:44:24:44:33 | taintedIKM : byte[] | provenance | |
35+
| KDFDataflowTest.java:44:9:44:15 | builder [post update] : Builder | KDFDataflowTest.java:46:34:46:40 | builder : Builder | provenance | |
36+
| KDFDataflowTest.java:44:24:44:33 | taintedIKM : byte[] | KDFDataflowTest.java:44:9:44:15 | builder [post update] : Builder | provenance | MaD:2 |
37+
| KDFDataflowTest.java:46:34:46:40 | builder : Builder | KDFDataflowTest.java:46:34:46:74 | thenExpand(...) : ExtractThenExpand | provenance | MaD:4 |
38+
| KDFDataflowTest.java:46:34:46:74 | thenExpand(...) : ExtractThenExpand | KDFDataflowTest.java:49:40:49:43 | spec : ExtractThenExpand | provenance | |
39+
| KDFDataflowTest.java:49:25:49:44 | deriveData(...) : byte[] | KDFDataflowTest.java:50:14:50:19 | result | provenance | |
40+
| KDFDataflowTest.java:49:40:49:43 | spec : ExtractThenExpand | KDFDataflowTest.java:49:25:49:44 | deriveData(...) : byte[] | provenance | MaD:7 |
41+
| KDFDataflowTest.java:53:48:53:64 | taintedIKM : byte[] | KDFDataflowTest.java:54:89:54:98 | taintedIKM : byte[] | provenance | |
42+
| KDFDataflowTest.java:54:53:54:106 | new SecretKeySpec(...) : SecretKeySpec | KDFDataflowTest.java:56:13:56:21 | secretKey : SecretKeySpec | provenance | |
43+
| KDFDataflowTest.java:54:89:54:98 | taintedIKM : byte[] | KDFDataflowTest.java:54:53:54:106 | new SecretKeySpec(...) : SecretKeySpec | provenance | MaD:6 |
44+
| KDFDataflowTest.java:55:34:56:45 | expandOnly(...) : Expand | KDFDataflowTest.java:59:40:59:43 | spec : Expand | provenance | |
45+
| KDFDataflowTest.java:56:13:56:21 | secretKey : SecretKeySpec | KDFDataflowTest.java:55:34:56:45 | expandOnly(...) : Expand | provenance | MaD:5 |
46+
| KDFDataflowTest.java:59:25:59:44 | deriveData(...) : byte[] | KDFDataflowTest.java:60:14:60:19 | result | provenance | |
47+
| KDFDataflowTest.java:59:40:59:43 | spec : Expand | KDFDataflowTest.java:59:25:59:44 | deriveData(...) : byte[] | provenance | MaD:7 |
48+
nodes
49+
| KDFDataflowTest.java:12:28:12:37 | source(...) : String | semmle.label | source(...) : String |
50+
| KDFDataflowTest.java:13:31:13:39 | userInput : String | semmle.label | userInput : String |
51+
| KDFDataflowTest.java:13:31:13:50 | getBytes(...) : byte[] | semmle.label | getBytes(...) : byte[] |
52+
| KDFDataflowTest.java:15:28:15:39 | taintedBytes : byte[] | semmle.label | taintedBytes : byte[] |
53+
| KDFDataflowTest.java:16:29:16:40 | taintedBytes : byte[] | semmle.label | taintedBytes : byte[] |
54+
| KDFDataflowTest.java:17:25:17:36 | taintedBytes : byte[] | semmle.label | taintedBytes : byte[] |
55+
| KDFDataflowTest.java:18:33:18:44 | taintedBytes : byte[] | semmle.label | taintedBytes : byte[] |
56+
| KDFDataflowTest.java:22:43:22:59 | taintedIKM : byte[] | semmle.label | taintedIKM : byte[] |
57+
| KDFDataflowTest.java:24:9:24:15 | builder [post update] : Builder | semmle.label | builder [post update] : Builder |
58+
| KDFDataflowTest.java:24:24:24:33 | taintedIKM : byte[] | semmle.label | taintedIKM : byte[] |
59+
| KDFDataflowTest.java:25:34:25:40 | builder : Builder | semmle.label | builder : Builder |
60+
| KDFDataflowTest.java:25:34:25:74 | thenExpand(...) : ExtractThenExpand | semmle.label | thenExpand(...) : ExtractThenExpand |
61+
| KDFDataflowTest.java:28:25:28:44 | deriveData(...) : byte[] | semmle.label | deriveData(...) : byte[] |
62+
| KDFDataflowTest.java:28:40:28:43 | spec : ExtractThenExpand | semmle.label | spec : ExtractThenExpand |
63+
| KDFDataflowTest.java:29:14:29:19 | result | semmle.label | result |
64+
| KDFDataflowTest.java:32:44:32:60 | taintedIKM : byte[] | semmle.label | taintedIKM : byte[] |
65+
| KDFDataflowTest.java:34:46:34:72 | addIKM(...) : Builder | semmle.label | addIKM(...) : Builder |
66+
| KDFDataflowTest.java:34:62:34:71 | taintedIKM : byte[] | semmle.label | taintedIKM : byte[] |
67+
| KDFDataflowTest.java:35:34:35:41 | builder2 : Builder | semmle.label | builder2 : Builder |
68+
| KDFDataflowTest.java:35:34:35:75 | thenExpand(...) : ExtractThenExpand | semmle.label | thenExpand(...) : ExtractThenExpand |
69+
| KDFDataflowTest.java:38:25:38:44 | deriveData(...) : byte[] | semmle.label | deriveData(...) : byte[] |
70+
| KDFDataflowTest.java:38:40:38:43 | spec : ExtractThenExpand | semmle.label | spec : ExtractThenExpand |
71+
| KDFDataflowTest.java:39:14:39:19 | result | semmle.label | result |
72+
| KDFDataflowTest.java:42:40:42:56 | taintedIKM : byte[] | semmle.label | taintedIKM : byte[] |
73+
| KDFDataflowTest.java:44:9:44:15 | builder [post update] : Builder | semmle.label | builder [post update] : Builder |
74+
| KDFDataflowTest.java:44:24:44:33 | taintedIKM : byte[] | semmle.label | taintedIKM : byte[] |
75+
| KDFDataflowTest.java:46:34:46:40 | builder : Builder | semmle.label | builder : Builder |
76+
| KDFDataflowTest.java:46:34:46:74 | thenExpand(...) : ExtractThenExpand | semmle.label | thenExpand(...) : ExtractThenExpand |
77+
| KDFDataflowTest.java:49:25:49:44 | deriveData(...) : byte[] | semmle.label | deriveData(...) : byte[] |
78+
| KDFDataflowTest.java:49:40:49:43 | spec : ExtractThenExpand | semmle.label | spec : ExtractThenExpand |
79+
| KDFDataflowTest.java:50:14:50:19 | result | semmle.label | result |
80+
| KDFDataflowTest.java:53:48:53:64 | taintedIKM : byte[] | semmle.label | taintedIKM : byte[] |
81+
| KDFDataflowTest.java:54:53:54:106 | new SecretKeySpec(...) : SecretKeySpec | semmle.label | new SecretKeySpec(...) : SecretKeySpec |
82+
| KDFDataflowTest.java:54:89:54:98 | taintedIKM : byte[] | semmle.label | taintedIKM : byte[] |
83+
| KDFDataflowTest.java:55:34:56:45 | expandOnly(...) : Expand | semmle.label | expandOnly(...) : Expand |
84+
| KDFDataflowTest.java:56:13:56:21 | secretKey : SecretKeySpec | semmle.label | secretKey : SecretKeySpec |
85+
| KDFDataflowTest.java:59:25:59:44 | deriveData(...) : byte[] | semmle.label | deriveData(...) : byte[] |
86+
| KDFDataflowTest.java:59:40:59:43 | spec : Expand | semmle.label | spec : Expand |
87+
| KDFDataflowTest.java:60:14:60:19 | result | semmle.label | result |
88+
subpaths
89+
testFailures
Lines changed: 3 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,3 @@
1-
import java
2-
import semmle.code.java.dataflow.TaintTracking
3-
4-
module Config implements DataFlow::ConfigSig {
5-
predicate isSource(DataFlow::Node n) {
6-
exists(ArrayAccess aa |
7-
aa.getArray().(VarAccess).getVariable().hasName("args") and
8-
n.asExpr() = aa
9-
)
10-
}
11-
12-
predicate isSink(DataFlow::Node n) {
13-
exists(MethodCall ma |
14-
ma.getMethod().hasName("sink") and
15-
n.asExpr() = ma.getAnArgument()
16-
)
17-
}
18-
}
19-
20-
module Flow = TaintTracking::Global<Config>;
21-
22-
from DataFlow::Node src, DataFlow::Node sink
23-
where Flow::flow(src, sink)
24-
select src, sink
1+
import utils.test.InlineFlowTest
2+
import TaintFlowTest<DefaultFlowConfig>
3+
import TaintFlow::PathGraph

0 commit comments

Comments
 (0)