Skip to content

Commit 1485f7c

Browse files
committed
Java: model some new Set,List,Map methods
Models the taint propagation for the copyOf(..), of(..), ofEntries(..) and entry(..) methods
1 parent c629f6b commit 1485f7c

File tree

4 files changed

+91
-22
lines changed

4 files changed

+91
-22
lines changed

java/ql/src/semmle/code/java/dataflow/internal/ContainerFlow.qll

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,34 @@ private predicate taintPreservingArgumentToMethod(Method method, int arg) {
180180
or
181181
method.hasName(["nCopies", "singletonMap"]) and arg = 1
182182
)
183+
or
184+
method
185+
.getDeclaringType()
186+
.getSourceDeclaration()
187+
.hasQualifiedName("java.util", ["List", "Map", "Set"]) and
188+
method.hasName("copyOf") and
189+
arg = 0
190+
or
191+
method.getDeclaringType().getSourceDeclaration().hasQualifiedName("java.util", "Map") and
192+
(
193+
method.hasName("of") and
194+
arg = any(int i | i in [1 .. 10] | 2 * i - 1)
195+
or
196+
method.hasName("entry") and
197+
arg = 1
198+
)
199+
}
200+
201+
/**
202+
* Holds if `method` is a library method that returns tainted data if any
203+
* of its arguments are tainted.
204+
*/
205+
private predicate taintPreservingArgumentToMethod(Method method) {
206+
method.getDeclaringType().getSourceDeclaration().hasQualifiedName("java.util", ["Set", "List"]) and
207+
method.hasName("of")
208+
or
209+
method.getDeclaringType().getSourceDeclaration().hasQualifiedName("java.util", "Map") and
210+
method.hasName("ofEntries")
183211
}
184212

185213
/**
@@ -208,11 +236,13 @@ private predicate argToQualifierStep(Expr tracked, Expr sink) {
208236

209237
/** Access to a method that passes taint from an argument. */
210238
private predicate argToMethodStep(Expr tracked, MethodAccess sink) {
211-
exists(Method m, int i |
212-
m = sink.getMethod() and
213-
taintPreservingArgumentToMethod(m, i) and
239+
exists(int i |
240+
taintPreservingArgumentToMethod(sink.getMethod(), i) and
214241
tracked = sink.getArgument(i)
215242
)
243+
or
244+
taintPreservingArgumentToMethod(sink.getMethod()) and
245+
tracked = sink.getAnArgument()
216246
}
217247

218248
/**

java/ql/test/library-tests/dataflow/local-additional-taint/CollectionsTest.java

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
import java.util.Collections;
22
import java.util.Enumeration;
33
import java.util.List;
4+
import java.util.Set;
5+
import java.util.Map;
46

57
class CollectionsTest {
6-
public static void taintSteps(List<String> list, List<String> other, Enumeration enumeration) {
8+
public static void taintSteps(List<String> list, List<String> other, Enumeration enumeration, Map<String,String> map) {
79
Collections.addAll(list);
810
Collections.addAll(list, "one");
911
Collections.addAll(list, "two", "three");
@@ -17,6 +19,22 @@ public static void taintSteps(List<String> list, List<String> other, Enumeration
1719
Collections.copy(list, other);
1820
Collections.nCopies(10, "item");
1921
Collections.replaceAll(list, "search", "replace");
22+
23+
List.of();
24+
java.util.List.of("a");
25+
List.of("b", "c");
26+
java.util.List.copyOf(list);
27+
Set.of();
28+
Set.of("d");
29+
Set.of("e" , "f");
30+
Set.copyOf(list);
31+
Map.of();
32+
Map.of("k", "v");
33+
Map.of("k1", "v1", "k2", "v2");
34+
Map.copyOf(map);
35+
Map.ofEntries();
36+
Map.ofEntries(Map.entry("k3", "v3"));
37+
Map.ofEntries(Map.entry("k4", "v4"), Map.entry("k5", "v5"));
2038
}
2139
}
2240

java/ql/test/library-tests/dataflow/local-additional-taint/localAdditionalTaintStep.expected

Lines changed: 38 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,41 @@
1-
| CollectionsTest.java:8:28:8:32 | "one" | CollectionsTest.java:8:3:8:33 | new ..[] { .. } |
2-
| CollectionsTest.java:8:28:8:32 | "one" | CollectionsTest.java:8:22:8:25 | list [post update] |
3-
| CollectionsTest.java:9:28:9:32 | "two" | CollectionsTest.java:9:3:9:42 | new ..[] { .. } |
4-
| CollectionsTest.java:9:28:9:32 | "two" | CollectionsTest.java:9:22:9:25 | list [post update] |
5-
| CollectionsTest.java:9:35:9:41 | "three" | CollectionsTest.java:9:3:9:42 | new ..[] { .. } |
6-
| CollectionsTest.java:9:35:9:41 | "three" | CollectionsTest.java:9:22:9:25 | list [post update] |
7-
| CollectionsTest.java:10:28:10:49 | new String[] | CollectionsTest.java:10:22:10:25 | list [post update] |
8-
| CollectionsTest.java:10:28:10:49 | {...} | CollectionsTest.java:10:28:10:49 | new String[] |
9-
| CollectionsTest.java:10:42:10:47 | "four" | CollectionsTest.java:10:28:10:49 | {...} |
10-
| CollectionsTest.java:12:27:12:30 | list | CollectionsTest.java:12:3:12:45 | checkedList(...) |
11-
| CollectionsTest.java:13:19:13:22 | list | CollectionsTest.java:13:3:13:23 | min(...) |
12-
| CollectionsTest.java:14:27:14:30 | list | CollectionsTest.java:14:3:14:31 | enumeration(...) |
13-
| CollectionsTest.java:15:20:15:30 | enumeration | CollectionsTest.java:15:3:15:31 | list(...) |
14-
| CollectionsTest.java:16:35:16:41 | "value" | CollectionsTest.java:16:3:16:42 | singletonMap(...) |
15-
| CollectionsTest.java:17:26:17:30 | other | CollectionsTest.java:17:20:17:23 | list [post update] |
16-
| CollectionsTest.java:18:27:18:32 | "item" | CollectionsTest.java:18:3:18:33 | nCopies(...) |
17-
| CollectionsTest.java:19:42:19:50 | "replace" | CollectionsTest.java:19:26:19:29 | list [post update] |
1+
| CollectionsTest.java:10:28:10:32 | "one" | CollectionsTest.java:10:3:10:33 | new ..[] { .. } |
2+
| CollectionsTest.java:10:28:10:32 | "one" | CollectionsTest.java:10:22:10:25 | list [post update] |
3+
| CollectionsTest.java:11:28:11:32 | "two" | CollectionsTest.java:11:3:11:42 | new ..[] { .. } |
4+
| CollectionsTest.java:11:28:11:32 | "two" | CollectionsTest.java:11:22:11:25 | list [post update] |
5+
| CollectionsTest.java:11:35:11:41 | "three" | CollectionsTest.java:11:3:11:42 | new ..[] { .. } |
6+
| CollectionsTest.java:11:35:11:41 | "three" | CollectionsTest.java:11:22:11:25 | list [post update] |
7+
| CollectionsTest.java:12:28:12:49 | new String[] | CollectionsTest.java:12:22:12:25 | list [post update] |
8+
| CollectionsTest.java:12:28:12:49 | {...} | CollectionsTest.java:12:28:12:49 | new String[] |
9+
| CollectionsTest.java:12:42:12:47 | "four" | CollectionsTest.java:12:28:12:49 | {...} |
10+
| CollectionsTest.java:14:27:14:30 | list | CollectionsTest.java:14:3:14:45 | checkedList(...) |
11+
| CollectionsTest.java:15:19:15:22 | list | CollectionsTest.java:15:3:15:23 | min(...) |
12+
| CollectionsTest.java:16:27:16:30 | list | CollectionsTest.java:16:3:16:31 | enumeration(...) |
13+
| CollectionsTest.java:17:20:17:30 | enumeration | CollectionsTest.java:17:3:17:31 | list(...) |
14+
| CollectionsTest.java:18:35:18:41 | "value" | CollectionsTest.java:18:3:18:42 | singletonMap(...) |
15+
| CollectionsTest.java:19:26:19:30 | other | CollectionsTest.java:19:20:19:23 | list [post update] |
16+
| CollectionsTest.java:20:27:20:32 | "item" | CollectionsTest.java:20:3:20:33 | nCopies(...) |
17+
| CollectionsTest.java:21:42:21:50 | "replace" | CollectionsTest.java:21:26:21:29 | list [post update] |
18+
| CollectionsTest.java:24:21:24:23 | "a" | CollectionsTest.java:24:3:24:24 | of(...) |
19+
| CollectionsTest.java:25:11:25:13 | "b" | CollectionsTest.java:25:3:25:19 | of(...) |
20+
| CollectionsTest.java:25:16:25:18 | "c" | CollectionsTest.java:25:3:25:19 | of(...) |
21+
| CollectionsTest.java:26:25:26:28 | list | CollectionsTest.java:26:3:26:29 | copyOf(...) |
22+
| CollectionsTest.java:28:10:28:12 | "d" | CollectionsTest.java:28:3:28:13 | of(...) |
23+
| CollectionsTest.java:29:10:29:12 | "e" | CollectionsTest.java:29:3:29:19 | of(...) |
24+
| CollectionsTest.java:29:16:29:18 | "f" | CollectionsTest.java:29:3:29:19 | of(...) |
25+
| CollectionsTest.java:30:14:30:17 | list | CollectionsTest.java:30:3:30:18 | copyOf(...) |
26+
| CollectionsTest.java:32:15:32:17 | "v" | CollectionsTest.java:32:3:32:18 | of(...) |
27+
| CollectionsTest.java:33:16:33:19 | "v1" | CollectionsTest.java:33:3:33:32 | of(...) |
28+
| CollectionsTest.java:33:28:33:31 | "v2" | CollectionsTest.java:33:3:33:32 | of(...) |
29+
| CollectionsTest.java:34:14:34:16 | map | CollectionsTest.java:34:3:34:17 | copyOf(...) |
30+
| CollectionsTest.java:36:17:36:37 | entry(...) | CollectionsTest.java:36:3:36:38 | new ..[] { .. } |
31+
| CollectionsTest.java:36:17:36:37 | entry(...) | CollectionsTest.java:36:3:36:38 | ofEntries(...) |
32+
| CollectionsTest.java:36:33:36:36 | "v3" | CollectionsTest.java:36:17:36:37 | entry(...) |
33+
| CollectionsTest.java:37:17:37:37 | entry(...) | CollectionsTest.java:37:3:37:61 | new ..[] { .. } |
34+
| CollectionsTest.java:37:17:37:37 | entry(...) | CollectionsTest.java:37:3:37:61 | ofEntries(...) |
35+
| CollectionsTest.java:37:33:37:36 | "v4" | CollectionsTest.java:37:17:37:37 | entry(...) |
36+
| CollectionsTest.java:37:40:37:60 | entry(...) | CollectionsTest.java:37:3:37:61 | new ..[] { .. } |
37+
| CollectionsTest.java:37:40:37:60 | entry(...) | CollectionsTest.java:37:3:37:61 | ofEntries(...) |
38+
| CollectionsTest.java:37:56:37:59 | "v5" | CollectionsTest.java:37:40:37:60 | entry(...) |
1839
| Test.java:24:32:24:38 | string2 | Test.java:24:17:24:39 | decode(...) |
1940
| Test.java:25:46:25:51 | bytes2 | Test.java:25:31:25:52 | encode(...) |
2041
| Test.java:27:34:27:40 | string2 | Test.java:27:13:27:41 | decode(...) |
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../stubs/apache-commons-codec-1.14
1+
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../stubs/apache-commons-codec-1.14 -source 14 -target 14

0 commit comments

Comments
 (0)