Skip to content

Commit a4b0041

Browse files
Better looksLikeResolveClassStep() predicate
1 parent 1d3eb57 commit a4b0041

File tree

4 files changed

+19
-8
lines changed

4 files changed

+19
-8
lines changed

java/ql/src/semmle/code/java/frameworks/Jackson.qll

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -156,19 +156,17 @@ predicate hasArgumentWithUnsafeJacksonAnnotation(MethodAccess call) {
156156

157157
/**
158158
* Holds if `fromNode` to `toNode` is a dataflow step that looks like resolving a class.
159-
* A method probably resolves a class if it is external, takes a string, returns a type descriptor
159+
* A method probably resolves a class if takes a string, returns a type descriptor,
160160
* and its name contains "resolve", "load", etc.
161161
*
162162
* Any method call that satisfies the rule above is assumed to propagate taint from its string arguments,
163163
* so methods that accept user-controlled data but sanitize it or use it for some
164164
* completely different purpose before returning a type descriptor could result in false positives.
165165
*/
166166
predicate looksLikeResolveClassStep(DataFlow::Node fromNode, DataFlow::Node toNode) {
167-
exists(MethodAccess ma, Method m, int i, Expr arg |
168-
m = ma.getMethod() and arg = ma.getArgument(i)
169-
|
167+
exists(MethodAccess ma, Method m, Expr arg | m = ma.getMethod() and arg = ma.getAnArgument() |
170168
m.getReturnType() instanceof JacksonTypeDescriptorType and
171-
m.getName().toLowerCase().regexpMatch("resolve|load|class|type") and
169+
m.getName().toLowerCase().regexpMatch("(.*)(resolve|load|class|type)(.*)") and
172170
arg.getType() instanceof TypeString and
173171
arg = fromNode.asExpr() and
174172
ma = toNode.asExpr()

java/ql/test/query-tests/security/CWE-502/JacksonTest.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import com.fasterxml.jackson.annotation.JsonTypeInfo;
22
import com.fasterxml.jackson.core.JsonFactory;
3+
import com.fasterxml.jackson.databind.JavaType;
34
import com.fasterxml.jackson.databind.ObjectMapper;
45
import com.fasterxml.jackson.databind.json.JsonMapper;
56
import com.fasterxml.jackson.databind.jsontype.BasicPolymorphicTypeValidator;
@@ -179,12 +180,12 @@ private static void testUnsafeDeserializationWithUnsafeClassAndCustomTypeResolve
179180
String data = parts[0];
180181
String type = parts[1];
181182
ObjectMapper mapper = new ObjectMapper();
182-
mapper.readValue(data, resolveTypeImpl(type)); // $unsafeDeserialization
183+
mapper.readValue(data, resolveImpl(type, mapper)); // $unsafeDeserialization
183184
});
184185
}
185186

186-
private static Class resolveTypeImpl(String type) throws Exception {
187-
return Class.forName(type);
187+
private static JavaType resolveImpl(String type, ObjectMapper mapper) throws Exception {
188+
return mapper.constructType(Class.forName(type));
188189
}
189190
}
190191

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
package com.fasterxml.jackson.databind;
2+
3+
public class JavaType {}

java/ql/test/stubs/jackson-databind-2.10/com/fasterxml/jackson/databind/ObjectMapper.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import com.fasterxml.jackson.core.JsonParser;
44
import com.fasterxml.jackson.core.TreeNode;
55
import com.fasterxml.jackson.databind.jsontype.PolymorphicTypeValidator;
6+
import java.lang.reflect.Type;
67
import java.io.*;
78
import java.util.*;
89

@@ -54,6 +55,10 @@ public <T> T readValue(String content, Class<T> valueType) {
5455
return null;
5556
}
5657

58+
public <T> T readValue(String content, JavaType valueType) {
59+
return null;
60+
}
61+
5762
public <T> MappingIterator<T> readValues(JsonParser p, Class<T> valueType) {
5863
return null;
5964
}
@@ -65,4 +70,8 @@ public <T> T treeToValue(TreeNode n, Class<T> valueType) {
6570
public JsonNode readTree(String content) {
6671
return null;
6772
}
73+
74+
public JavaType constructType(Type t) {
75+
return null;
76+
}
6877
}

0 commit comments

Comments
 (0)