Skip to content

Commit 5a2bdc9

Browse files
committed
Jackson taint tracking of elements
Signed-off-by: Jonathan Leitschuh <Jonathan.Leitschuh@gmail.com>
1 parent 8fecc15 commit 5a2bdc9

File tree

2 files changed

+45
-1
lines changed

2 files changed

+45
-1
lines changed

java/ql/lib/semmle/code/java/frameworks/jackson/JacksonSerializability.qll

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,7 @@ private class JacksonModel extends SummaryModelCsv {
285285
[
286286
"com.fasterxml.jackson.databind;ObjectMapper;true;valueToTree;;;Argument[0];ReturnValue;taint",
287287
"com.fasterxml.jackson.databind;ObjectMapper;true;valueToTree;;;MapValue of Argument[0];ReturnValue;taint",
288+
"com.fasterxml.jackson.databind;ObjectMapper;true;valueToTree;;;Element of MapValue of Argument[0];ReturnValue;taint",
288289
"com.fasterxml.jackson.databind;ObjectMapper;true;convertValue;;;Argument[0];ReturnValue;taint",
289290
"com.fasterxml.jackson.databind;ObjectMapper;false;createParser;;;Argument[0];ReturnValue;taint",
290291
"com.fasterxml.jackson.databind;ObjectReader;false;createParser;;;Argument[0];ReturnValue;taint",

java/ql/test/library-tests/frameworks/ratpack/resources/IntegrationTest.java

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,15 @@ void test2(Context ctx) {
6565
void test3() {
6666
Object value = extractSingleValueIfPossible(ImmutableList.of("a", taint()));
6767
sink(value); //$hasTaintFlow
68+
List<Object> values = (List<Object>) value;
69+
sink(values.get(1)); //$hasTaintFlow
70+
Map<String, Object> weirdMap = new HashMap<>();
71+
weirdMap.put("a", value);
72+
weirdMap.forEach((key, mapValue) -> {
73+
sink(mapValue); //$hasTaintFlow
74+
List<Object> values2 = (List<Object>) mapValue;
75+
sink(values2.get(0)); //$hasTaintFlow
76+
});
6877
}
6978

7079
void test4(Context ctx) {
@@ -74,8 +83,32 @@ void test4(Context ctx) {
7483
filterAndMerge(pojoForm, mergedParams, name -> false);
7584
return mergedParams;
7685
}).then(pojoMap -> {
77-
sinlk(pojoMap); //$hasTaintFlow
86+
sink(pojoMap.keySet().iterator().next()); //$hasTaintFlow
7887
sink(pojoMap.get("value")); //$hasTaintFlow
88+
pojoMap.forEach((key, value) -> {
89+
sink(key); //$hasTaintFlow
90+
sink(value); //$hasTaintFlow
91+
List<Object> values = (List<Object>) value;
92+
sink(values.get(0)); //$hasTaintFlow
93+
});
94+
});
95+
}
96+
97+
void test5(Context ctx) {
98+
parseToForm(ctx, Pojo.class)
99+
.map(pojoForm -> {
100+
Map<String, Object> mergedParams = new HashMap<>();
101+
filterAndMerge_2(pojoForm, mergedParams, name -> false);
102+
return mergedParams;
103+
}).then(pojoMap -> {
104+
sink(pojoMap.keySet().iterator().next()); //TODO:$hasTaintFlow
105+
sink(pojoMap.get("value")); //TODO:$hasTaintFlow
106+
pojoMap.forEach((key, value) -> {
107+
sink(key); //TODO:$hasTaintFlow
108+
sink(value); //TODO:$hasTaintFlow
109+
List<Object> values = (List<Object>) value;
110+
sink(values.get(0)); //TODO:$hasTaintFlow
111+
});
79112
});
80113
}
81114

@@ -138,6 +171,16 @@ private ObjectNode toObjectNode(MultiValueMap<String, String> params, Action<? s
138171
}
139172

140173
private static void filterAndMerge(MultiValueMap<String, String> params, Map<String, Object> defaults, Predicate<String> filter) {
174+
for(Map.Entry<String, Collection<String>> entry : params.asMultimap().asMap().entrySet()) {
175+
String name = entry.getKey();
176+
Collection<String> values = entry.getValue();
177+
if (!isEmptyAndHasDefault(name, values, defaults) && !filter.test(name)) {
178+
defaults.put(name, extractSingleValueIfPossible(values));
179+
}
180+
}
181+
}
182+
183+
private static void filterAndMerge_2(MultiValueMap<String, String> params, Map<String, Object> defaults, Predicate<String> filter) {
141184
params.asMultimap().asMap().forEach((name, values) -> {
142185
if (!isEmptyAndHasDefault(name, values, defaults) && !filter.test(name)) {
143186
defaults.put(name, extractSingleValueIfPossible(values));

0 commit comments

Comments
 (0)