mirror of
https://github.com/github/codeql.git
synced 2026-04-30 11:15:13 +02:00
Resove taint tracking issues from asMultimap
Signed-off-by: Jonathan Leitschuh <Jonathan.Leitschuh@gmail.com>
This commit is contained in:
@@ -81,7 +81,7 @@ private class RatpackModel extends SummaryModelCsv {
|
||||
"MultiValueMap;true;getAll;();;MapValue of Argument[-1];Element of MapValue of ReturnValue;value",
|
||||
"MultiValueMap;true;getAll;(Object);;MapValue of Argument[-1];Element of ReturnValue;value",
|
||||
"MultiValueMap;true;asMultimap;;;MapKey of Argument[-1];MapKey of ReturnValue;value",
|
||||
"MultiValueMap;true;asMultimap;;;MapValue of Argument[-1];Element of MapValue of ReturnValue;value"
|
||||
"MultiValueMap;true;asMultimap;;;MapValue of Argument[-1];MapValue of ReturnValue;value"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
|
||||
import ratpack.core.handling.Context;
|
||||
import ratpack.core.form.Form;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.List;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
public class CollectionPassingTest {
|
||||
|
||||
void sink(Object o) {}
|
||||
|
||||
String taint() {
|
||||
return null;
|
||||
}
|
||||
|
||||
void test_1(Context ctx) {
|
||||
// Given
|
||||
ctx
|
||||
.getRequest()
|
||||
.getBody()
|
||||
.map(data -> ctx.parse(data, Form.form()))
|
||||
.then(form -> {
|
||||
// When
|
||||
Map<String, Object> pojoMap = new HashMap<>();
|
||||
merge(form.asMultimap().asMap(), pojoMap);
|
||||
// Then
|
||||
sink(pojoMap.get("value")); //$hasTaintFlow
|
||||
pojoMap.forEach((key, value) -> {
|
||||
sink(value); //$hasTaintFlow
|
||||
List<Object> values = (List<Object>) value;
|
||||
sink(values.get(0)); //$hasTaintFlow
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
void test_2() {
|
||||
// Given
|
||||
Map<String, Collection<String>> taintedMap = new HashMap<>();
|
||||
taintedMap.put("value", ImmutableList.of(taint()));
|
||||
Map<String, Object> pojoMap = new HashMap<>();
|
||||
// When
|
||||
merge(taintedMap, pojoMap);
|
||||
// Then
|
||||
sink(pojoMap.get("value")); //$hasTaintFlow
|
||||
pojoMap.forEach((key, value) -> {
|
||||
sink(value); //$hasTaintFlow
|
||||
List<Object> values = (List<Object>) value;
|
||||
sink(values.get(0)); //$hasTaintFlow
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
private static void merge(Map<String, Collection<String>> params, Map<String, Object> defaults) {
|
||||
for(Map.Entry<String, Collection<String>> entry : params.entrySet()) {
|
||||
String name = entry.getKey();
|
||||
Collection<String> values = entry.getValue();
|
||||
defaults.put(name, extractSingleValueIfPossible(values));
|
||||
}
|
||||
}
|
||||
|
||||
private static Object extractSingleValueIfPossible(Collection<String> values) {
|
||||
return values.size() == 1 ? values.iterator().next() : ImmutableList.copyOf(values);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -31,9 +31,15 @@ class IntegrationTest {
|
||||
static class Pojo {
|
||||
String value;
|
||||
|
||||
List<String> values;
|
||||
|
||||
String getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
List<String> getValues() {
|
||||
return values;
|
||||
}
|
||||
}
|
||||
|
||||
private final ObjectMapper objectMapper = new ObjectMapper();
|
||||
@@ -112,6 +118,24 @@ class IntegrationTest {
|
||||
});
|
||||
}
|
||||
|
||||
void test6(Context ctx) {
|
||||
bindQuery(ctx, Pojo.class)
|
||||
.then(pojo -> {
|
||||
sink(pojo.getValue()); //$hasTaintFlow
|
||||
sink(pojo.getValues()); //$hasTaintFlow
|
||||
});
|
||||
}
|
||||
|
||||
public <T> Promise<T> bindQuery(Context ctx, Class<T> type) {
|
||||
return bindQuery(ctx, type, Action.noop());
|
||||
}
|
||||
|
||||
public <T> Promise<T> bindQuery(Context ctx, Class<T> type, Action<? super ImmutableMap.Builder<String, Object>> defaults) {
|
||||
return Promise.sync(() ->
|
||||
bind(ctx, toObjectNode(ctx.getRequest().getQueryParams(), defaults, name -> false), type)
|
||||
);
|
||||
}
|
||||
|
||||
private <T> Promise<T> bindJson(Context ctx, Class<T> type) {
|
||||
return ctx.getRequest().getBody()
|
||||
.map(data -> {
|
||||
@@ -215,4 +239,4 @@ class IntegrationTest {
|
||||
// empty
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -316,6 +316,5 @@ class Resource {
|
||||
.then(value -> {
|
||||
sink(value); // no tainted flow
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user