Merge branch 'main' into atorralba/promote-groovy-injection

This commit is contained in:
Tony Torralba
2021-08-03 09:53:46 +02:00
committed by GitHub
211 changed files with 5560 additions and 2147 deletions

View File

@@ -0,0 +1,160 @@
import org.springframework.http.ResponseEntity;
import org.springframework.http.MediaType;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Optional;
@RestController
public class SpringXSS {
@GetMapping
public static ResponseEntity<String> specificContentType(boolean safeContentType, boolean chainDirectly, String userControlled) {
ResponseEntity.BodyBuilder builder = ResponseEntity.ok();
if(safeContentType) {
if(chainDirectly) {
return builder.contentType(MediaType.TEXT_HTML).body(userControlled); // $xss
}
else {
ResponseEntity.BodyBuilder builder2 = builder.contentType(MediaType.TEXT_HTML);
return builder2.body(userControlled); // $xss
}
}
else {
if(chainDirectly) {
return builder.contentType(MediaType.APPLICATION_JSON).body(userControlled); // $SPURIOUS: xss
}
else {
ResponseEntity.BodyBuilder builder2 = builder.contentType(MediaType.APPLICATION_JSON);
return builder2.body(userControlled); // $SPURIOUS: xss
}
}
}
@GetMapping(value = "/xyz", produces = MediaType.APPLICATION_JSON_VALUE)
public static ResponseEntity<String> methodContentTypeSafe(String userControlled) {
return ResponseEntity.ok(userControlled);
}
@PostMapping(value = "/xyz", produces = MediaType.APPLICATION_JSON_VALUE)
public static ResponseEntity<String> methodContentTypeSafePost(String userControlled) {
return ResponseEntity.ok(userControlled);
}
@RequestMapping(value = "/xyz", produces = MediaType.APPLICATION_JSON_VALUE)
public static ResponseEntity<String> methodContentTypeSafeRequest(String userControlled) {
return ResponseEntity.ok(userControlled);
}
@GetMapping(value = "/xyz", produces = "application/json")
public static ResponseEntity<String> methodContentTypeSafeStringLiteral(String userControlled) {
return ResponseEntity.ok(userControlled);
}
@GetMapping(value = "/xyz", produces = MediaType.TEXT_HTML_VALUE)
public static ResponseEntity<String> methodContentTypeUnsafe(String userControlled) {
return ResponseEntity.ok(userControlled); // $MISSING: xss
}
@GetMapping(value = "/xyz", produces = "text/html")
public static ResponseEntity<String> methodContentTypeUnsafeStringLiteral(String userControlled) {
return ResponseEntity.ok(userControlled); // $xss
}
@GetMapping(value = "/xyz", produces = {MediaType.TEXT_HTML_VALUE, MediaType.APPLICATION_JSON_VALUE})
public static ResponseEntity<String> methodContentTypeMaybeSafe(String userControlled) {
return ResponseEntity.ok(userControlled); // $xss
}
@GetMapping(value = "/xyz", produces = MediaType.APPLICATION_JSON_VALUE)
public static ResponseEntity<String> methodContentTypeSafeOverriddenWithUnsafe(String userControlled) {
return ResponseEntity.ok().contentType(MediaType.TEXT_HTML).body(userControlled); // $MISSING: xss
}
@GetMapping(value = "/xyz", produces = MediaType.TEXT_HTML_VALUE)
public static ResponseEntity<String> methodContentTypeUnsafeOverriddenWithSafe(String userControlled) {
return ResponseEntity.ok().contentType(MediaType.APPLICATION_JSON).body(userControlled);
}
@GetMapping(value = "/xyz", produces = {"text/html", "application/json"})
public static ResponseEntity<String> methodContentTypeMaybeSafeStringLiterals(String userControlled, int constructionMethod) {
// Also try out some alternative constructors for the ResponseEntity:
switch(constructionMethod) {
case 0:
return ResponseEntity.ok(userControlled); // $xss
case 1:
return ResponseEntity.of(Optional.of(userControlled)); // $xss
case 2:
return ResponseEntity.ok().body(userControlled); // $xss
case 3:
return new ResponseEntity<String>(userControlled, HttpStatus.OK); // $xss
default:
return null;
}
}
@RestController
@RequestMapping(produces = {"application/json"})
private static class ClassContentTypeSafe {
@GetMapping(value = "/abc")
public ResponseEntity<String> test(String userControlled) {
return ResponseEntity.ok(userControlled); // $SPURIOUS: xss
}
@GetMapping(value = "/abc")
public String testDirectReturn(String userControlled) {
return userControlled; // $SPURIOUS: xss
}
@GetMapping(value = "/xyz", produces = {"text/html"})
public ResponseEntity<String> overridesWithUnsafe(String userControlled) {
return ResponseEntity.ok(userControlled); // $xss
}
@GetMapping(value = "/abc")
public ResponseEntity<String> overridesWithUnsafe2(String userControlled) {
return ResponseEntity.ok().contentType(MediaType.TEXT_HTML).body(userControlled); // $xss
}
}
@RestController
@RequestMapping(produces = {"text/html"})
private static class ClassContentTypeUnsafe {
@GetMapping(value = "/abc")
public ResponseEntity<String> test(String userControlled) {
return ResponseEntity.ok(userControlled); // $xss
}
@GetMapping(value = "/abc")
public String testDirectReturn(String userControlled) {
return userControlled; // $xss
}
@GetMapping(value = "/xyz", produces = {"application/json"})
public ResponseEntity<String> overridesWithSafe(String userControlled) {
return ResponseEntity.ok(userControlled); // $SPURIOUS: xss
}
@GetMapping(value = "/abc")
public ResponseEntity<String> overridesWithSafe2(String userControlled) {
return ResponseEntity.ok().contentType(MediaType.APPLICATION_JSON).body(userControlled); // $SPURIOUS: xss
}
}
@GetMapping(value = "/abc")
public static ResponseEntity<String> entityWithNoMediaType(String userControlled) {
return ResponseEntity.ok(userControlled); // $xss
}
@GetMapping(value = "/abc")
public static String stringWithNoMediaType(String userControlled) {
return userControlled; // $xss
}
}

View File

@@ -1 +1 @@
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../../../stubs/servlet-api-2.4:${testdir}/../../../../../stubs/javax-ws-rs-api-2.1.1/
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../../../stubs/servlet-api-2.4:${testdir}/../../../../../stubs/javax-ws-rs-api-2.1.1/:${testdir}/../../../../../stubs/springframework-5.3.8

View File

@@ -0,0 +1,96 @@
import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
import java.net.Socket;
import java.util.HashMap;
import javax.script.CompiledScript;
import javax.script.SimpleScriptContext;
import org.mvel2.MVEL;
import org.mvel2.MVELRuntime;
import org.mvel2.ParserContext;
import org.mvel2.compiler.CompiledAccExpression;
import org.mvel2.compiler.CompiledExpression;
import org.mvel2.compiler.ExecutableStatement;
import org.mvel2.compiler.ExpressionCompiler;
import org.mvel2.integration.impl.ImmutableDefaultFactory;
import org.mvel2.jsr223.MvelCompiledScript;
import org.mvel2.jsr223.MvelScriptEngine;
import org.mvel2.templates.TemplateCompiler;
import org.mvel2.templates.TemplateRuntime;
public class MvelInjectionTest {
public static void testWithMvelEval(Socket socket) throws IOException {
MVEL.eval(read(socket)); // $hasMvelInjection
}
public static void testWithMvelCompileAndExecute(Socket socket) throws IOException {
Serializable expression = MVEL.compileExpression(read(socket));
MVEL.executeExpression(expression); // $hasMvelInjection
}
public static void testWithExpressionCompiler(Socket socket) throws IOException {
ExpressionCompiler compiler = new ExpressionCompiler(read(socket));
ExecutableStatement statement = compiler.compile();
statement.getValue(new Object(), new ImmutableDefaultFactory()); // $hasMvelInjection
statement.getValue(new Object(), new Object(), new ImmutableDefaultFactory()); // $hasMvelInjection
}
public static void testWithCompiledExpressionGetDirectValue(Socket socket) throws IOException {
ExpressionCompiler compiler = new ExpressionCompiler(read(socket));
CompiledExpression expression = compiler.compile();
expression.getDirectValue(new Object(), new ImmutableDefaultFactory()); // $hasMvelInjection
}
public static void testCompiledAccExpressionGetValue(Socket socket) throws IOException {
CompiledAccExpression expression =
new CompiledAccExpression(read(socket).toCharArray(), Object.class, new ParserContext());
expression.getValue(new Object(), new ImmutableDefaultFactory()); // $hasMvelInjection
}
public static void testMvelScriptEngineCompileAndEvaluate(Socket socket) throws Exception {
String input = read(socket);
MvelScriptEngine engine = new MvelScriptEngine();
CompiledScript compiledScript = engine.compile(input);
compiledScript.eval(); // $hasMvelInjection
Serializable script = engine.compiledScript(input);
engine.evaluate(script, new SimpleScriptContext()); // $hasMvelInjection
}
public static void testMvelCompiledScriptCompileAndEvaluate(Socket socket) throws Exception {
MvelScriptEngine engine = new MvelScriptEngine();
ExpressionCompiler compiler = new ExpressionCompiler(read(socket));
ExecutableStatement statement = compiler.compile();
MvelCompiledScript script = new MvelCompiledScript(engine, statement);
script.eval(new SimpleScriptContext()); // $hasMvelInjection
}
public static void testTemplateRuntimeEval(Socket socket) throws Exception {
TemplateRuntime.eval(read(socket), new HashMap()); // $hasMvelInjection
}
public static void testTemplateRuntimeCompileTemplateAndExecute(Socket socket) throws Exception {
TemplateRuntime.execute(TemplateCompiler.compileTemplate(read(socket)), new HashMap()); // $hasMvelInjection
}
public static void testTemplateRuntimeCompileAndExecute(Socket socket) throws Exception {
TemplateCompiler compiler = new TemplateCompiler(read(socket));
TemplateRuntime.execute(compiler.compile(), new HashMap()); // $hasMvelInjection
}
public static void testMvelRuntimeExecute(Socket socket) throws Exception {
ExpressionCompiler compiler = new ExpressionCompiler(read(socket));
CompiledExpression expression = compiler.compile();
MVELRuntime.execute(false, expression, new Object(), new ImmutableDefaultFactory()); // $hasMvelInjection
}
public static String read(Socket socket) throws IOException {
try (InputStream is = socket.getInputStream()) {
byte[] bytes = new byte[1024];
int n = is.read(bytes);
return new String(bytes, 0, n);
}
}
}

View File

@@ -0,0 +1,22 @@
import java
import semmle.code.java.dataflow.TaintTracking
import semmle.code.java.dataflow.FlowSources
import semmle.code.java.security.MvelInjectionQuery
import TestUtilities.InlineExpectationsTest
class HasMvelInjectionTest extends InlineExpectationsTest {
HasMvelInjectionTest() { this = "HasMvelInjectionTest" }
override string getARelevantTag() { result = "hasMvelInjection" }
override predicate hasActualResult(Location location, string element, string tag, string value) {
tag = "hasMvelInjection" and
exists(DataFlow::Node src, DataFlow::Node sink, MvelInjectionFlowConfig conf |
conf.hasFlow(src, sink)
|
sink.getLocation() = location and
element = sink.toString() and
value = ""
)
}
}

View File

@@ -1 +1 @@
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../stubs/validation-api-2.0.1.Final:${testdir}/../../../stubs/springframework-5.3.8:${testdir}/../../../stubs/apache-commons-jexl-2.1.1:${testdir}/../../../stubs/apache-commons-jexl-3.1:${testdir}/../../../stubs/apache-commons-logging-1.2:${testdir}/../../../stubs/groovy-all-3.0.7:${testdir}/../../../stubs/servlet-api-2.4
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../stubs/validation-api-2.0.1.Final:${testdir}/../../../stubs/springframework-5.3.8:${testdir}/../../../stubs/apache-commons-jexl-2.1.1:${testdir}/../../../stubs/apache-commons-jexl-3.1:${testdir}/../../../stubs/apache-commons-logging-1.2:${testdir}/../../../stubs/mvel2-2.4.7:${testdir}/../../../stubs/groovy-all-3.0.7:${testdir}/../../../stubs/servlet-api-2.4:${testdir}/../../../stubs/scriptengine:${testdir}/../../../stubs/jsr223-api

View File

@@ -12,34 +12,34 @@ public class A {
public Object deserialize1(Socket sock) throws java.io.IOException, ClassNotFoundException {
InputStream inputStream = sock.getInputStream();
ObjectInputStream in = new ObjectInputStream(inputStream);
return in.readObject(); // unsafe
return in.readObject(); // $unsafeDeserialization
}
public Object deserialize2(Socket sock) throws java.io.IOException, ClassNotFoundException {
InputStream inputStream = sock.getInputStream();
ObjectInputStream in = new ObjectInputStream(inputStream);
return in.readUnshared(); // unsafe
return in.readUnshared(); // $unsafeDeserialization
}
public Object deserialize3(Socket sock) throws java.io.IOException {
InputStream inputStream = sock.getInputStream();
XMLDecoder d = new XMLDecoder(inputStream);
return d.readObject(); // unsafe
return d.readObject(); // $unsafeDeserialization
}
public Object deserialize4(Socket sock) throws java.io.IOException {
XStream xs = new XStream();
InputStream inputStream = sock.getInputStream();
Reader reader = new InputStreamReader(inputStream);
return xs.fromXML(reader); // unsafe
return xs.fromXML(reader); // $unsafeDeserialization
}
public void deserialize5(Socket sock) throws java.io.IOException {
Kryo kryo = new Kryo();
Input input = new Input(sock.getInputStream());
A a1 = kryo.readObject(input, A.class); // unsafe
A a2 = kryo.readObjectOrNull(input, A.class); // unsafe
Object o = kryo.readClassAndObject(input); // unsafe
A a1 = kryo.readObject(input, A.class); // $unsafeDeserialization
A a2 = kryo.readObjectOrNull(input, A.class); // $unsafeDeserialization
Object o = kryo.readClassAndObject(input); // $unsafeDeserialization
}
private Kryo getSafeKryo() throws java.io.IOException {
@@ -58,21 +58,21 @@ public class A {
public void deserializeSnakeYaml(Socket sock) throws java.io.IOException {
Yaml yaml = new Yaml();
InputStream input = sock.getInputStream();
Object o = yaml.load(input); //unsafe
Object o2 = yaml.loadAll(input); //unsafe
Object o3 = yaml.parse(new InputStreamReader(input)); //unsafe
A o4 = yaml.loadAs(input, A.class); //unsafe
A o5 = yaml.loadAs(new InputStreamReader(input), A.class); //unsafe
Object o = yaml.load(input); // $unsafeDeserialization
Object o2 = yaml.loadAll(input); // $unsafeDeserialization
Object o3 = yaml.parse(new InputStreamReader(input)); // $unsafeDeserialization
A o4 = yaml.loadAs(input, A.class); // $unsafeDeserialization
A o5 = yaml.loadAs(new InputStreamReader(input), A.class); // $unsafeDeserialization
}
public void deserializeSnakeYaml2(Socket sock) throws java.io.IOException {
Yaml yaml = new Yaml(new Constructor());
InputStream input = sock.getInputStream();
Object o = yaml.load(input); //unsafe
Object o2 = yaml.loadAll(input); //unsafe
Object o3 = yaml.parse(new InputStreamReader(input)); //unsafe
A o4 = yaml.loadAs(input, A.class); //unsafe
A o5 = yaml.loadAs(new InputStreamReader(input), A.class); //unsafe
Object o = yaml.load(input); // $unsafeDeserialization
Object o2 = yaml.loadAll(input); // $unsafeDeserialization
Object o3 = yaml.parse(new InputStreamReader(input)); // $unsafeDeserialization
A o4 = yaml.loadAs(input, A.class); // $unsafeDeserialization
A o5 = yaml.loadAs(new InputStreamReader(input), A.class); // $unsafeDeserialization
}
public void deserializeSnakeYaml3(Socket sock) throws java.io.IOException {
@@ -88,10 +88,10 @@ public class A {
public void deserializeSnakeYaml4(Socket sock) throws java.io.IOException {
Yaml yaml = new Yaml(new Constructor(A.class));
InputStream input = sock.getInputStream();
Object o = yaml.load(input); //unsafe
Object o2 = yaml.loadAll(input); //unsafe
Object o3 = yaml.parse(new InputStreamReader(input)); //unsafe
A o4 = yaml.loadAs(input, A.class); //unsafe
A o5 = yaml.loadAs(new InputStreamReader(input), A.class); //unsafe
Object o = yaml.load(input); // $unsafeDeserialization
Object o2 = yaml.loadAll(input); // $unsafeDeserialization
Object o3 = yaml.parse(new InputStreamReader(input)); // $unsafeDeserialization
A o4 = yaml.loadAs(input, A.class); // $unsafeDeserialization
A o5 = yaml.loadAs(new InputStreamReader(input), A.class); // $unsafeDeserialization
}
}

View File

@@ -5,14 +5,14 @@ import com.alibaba.fastjson.JSON;
public class B {
public Object deserializeJson1(Socket sock) throws java.io.IOException {
InputStream inputStream = sock.getInputStream();
return JSON.parseObject(inputStream, null); // unsafe
return JSON.parseObject(inputStream, null); // $unsafeDeserialization
}
public Object deserializeJson2(Socket sock) throws java.io.IOException {
InputStream inputStream = sock.getInputStream();
byte[] bytes = new byte[100];
inputStream.read(bytes);
return JSON.parse(bytes); // unsafe
return JSON.parse(bytes); // $unsafeDeserialization
}
public Object deserializeJson3(Socket sock) throws java.io.IOException {
@@ -20,7 +20,7 @@ public class B {
byte[] bytes = new byte[100];
inputStream.read(bytes);
String s = new String(bytes);
return JSON.parseObject(s); // unsafe
return JSON.parseObject(s); // $unsafeDeserialization
}
public Object deserializeJson4(Socket sock) throws java.io.IOException {
@@ -28,6 +28,6 @@ public class B {
byte[] bytes = new byte[100];
inputStream.read(bytes);
String s = new String(bytes);
return JSON.parse(s); // unsafe
return JSON.parse(s); // $unsafeDeserialization
}
}

View File

@@ -21,16 +21,16 @@ public class C {
@GetMapping(value = "jyaml")
public void bad1(HttpServletRequest request) throws Exception {
String data = request.getParameter("data");
Yaml.load(data); //bad
Yaml.loadStream(data); //bad
Yaml.loadStreamOfType(data, Object.class); //bad
Yaml.loadType(data, Object.class); //bad
Yaml.load(data); // $unsafeDeserialization
Yaml.loadStream(data); // $unsafeDeserialization
Yaml.loadStreamOfType(data, Object.class); // $unsafeDeserialization
Yaml.loadType(data, Object.class); // $unsafeDeserialization
org.ho.yaml.YamlConfig yamlConfig = new YamlConfig();
yamlConfig.load(data); //bad
yamlConfig.loadStream(data); //bad
yamlConfig.loadStreamOfType(data, Object.class); //bad
yamlConfig.loadType(data, Object.class); //bad
yamlConfig.load(data); // $unsafeDeserialization
yamlConfig.loadStream(data); // $unsafeDeserialization
yamlConfig.loadStreamOfType(data, Object.class); // $unsafeDeserialization
yamlConfig.loadType(data, Object.class); // $unsafeDeserialization
}
@GetMapping(value = "jsonio")
@@ -40,19 +40,19 @@ public class C {
HashMap hashMap = new HashMap();
hashMap.put("USE_MAPS", true);
JsonReader.jsonToJava(data); //bad
JsonReader.jsonToJava(data); // $unsafeDeserialization
JsonReader jr = new JsonReader(data, null); //bad
jr.readObject();
JsonReader jr = new JsonReader(data, null);
jr.readObject(); // $unsafeDeserialization
}
@GetMapping(value = "yamlbeans")
public void bad3(HttpServletRequest request) throws Exception {
String data = request.getParameter("data");
YamlReader r = new YamlReader(data);
r.read(); //bad
r.read(Object.class); //bad
r.read(Object.class, Object.class); //bad
r.read(); // $unsafeDeserialization
r.read(Object.class); // $unsafeDeserialization
r.read(Object.class, Object.class); // $unsafeDeserialization
}
@GetMapping(value = "hessian")
@@ -60,8 +60,8 @@ public class C {
byte[] bytes = request.getParameter("data").getBytes();
ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
HessianInput hessianInput = new HessianInput(bis);
hessianInput.readObject(); //bad
hessianInput.readObject(Object.class); //bad
hessianInput.readObject(); // $unsafeDeserialization
hessianInput.readObject(Object.class); // $unsafeDeserialization
}
@GetMapping(value = "hessian2")
@@ -69,14 +69,14 @@ public class C {
byte[] bytes = request.getParameter("data").getBytes();
ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
Hessian2Input hessianInput = new Hessian2Input(bis);
hessianInput.readObject(); //bad
hessianInput.readObject(Object.class); //bad
hessianInput.readObject(); // $unsafeDeserialization
hessianInput.readObject(Object.class); // $unsafeDeserialization
}
@GetMapping(value = "castor")
public void bad6(HttpServletRequest request) throws Exception {
Unmarshaller unmarshaller = new Unmarshaller();
unmarshaller.unmarshal(new StringReader(request.getParameter("data"))); //bad
unmarshaller.unmarshal(new StringReader(request.getParameter("data"))); // $unsafeDeserialization
}
@GetMapping(value = "burlap")
@@ -84,11 +84,11 @@ public class C {
byte[] serializedData = request.getParameter("data").getBytes();
ByteArrayInputStream is = new ByteArrayInputStream(serializedData);
BurlapInput burlapInput = new BurlapInput(is);
burlapInput.readObject(); //bad
burlapInput.readObject(); // $unsafeDeserialization
BurlapInput burlapInput1 = new BurlapInput();
burlapInput1.init(is);
burlapInput1.readObject(); //bad
burlapInput1.readObject(); // $unsafeDeserialization
}
@GetMapping(value = "jsonio1")

View File

@@ -0,0 +1,209 @@
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.json.JsonMapper;
import com.fasterxml.jackson.databind.jsontype.BasicPolymorphicTypeValidator;
import com.fasterxml.jackson.databind.jsontype.PolymorphicTypeValidator;
import java.io.IOException;
import java.io.Serializable;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.List;
public class JacksonTest {
public static void withSocket(Action<String> action) throws Exception {
try (ServerSocket serverSocket = new ServerSocket(0)) {
try (Socket socket = serverSocket.accept()) {
byte[] bytes = new byte[1024];
int n = socket.getInputStream().read(bytes);
String jexlExpr = new String(bytes, 0, n);
action.run(jexlExpr);
}
}
}
}
interface Action<T> {
void run(T object) throws Exception;
}
abstract class PhoneNumber implements Serializable {
public int areaCode;
public int local;
}
class DomesticNumber extends PhoneNumber {
}
class InternationalNumber extends PhoneNumber {
public int countryCode;
}
class Employee extends Person {
}
class Person {
public String name;
public int age;
// this annotation enables polymorphic type handling
@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS)
public Object phone;
}
class Task {
public Person assignee;
}
class Tag implements Serializable {
public String title;
}
class Cat {
public String name;
public Serializable tag;
}
class UnsafePersonDeserialization {
// BAD: Person has a field with an annotation that enables polymorphic type
// handling
private static void testUnsafeDeserialization() throws Exception {
JacksonTest.withSocket(string -> {
ObjectMapper mapper = new ObjectMapper();
mapper.readValue(string, Person.class); // $unsafeDeserialization
});
}
// BAD: Employee extends Person that has a field with an annotation that enables
// polymorphic type handling
private static void testUnsafeDeserializationWithExtendedClass() throws Exception {
JacksonTest.withSocket(string -> {
ObjectMapper mapper = new ObjectMapper();
mapper.readValue(string, Employee.class); // $unsafeDeserialization
});
}
// BAD: Task has a Person field that has a field with an annotation that enables
// polymorphic type handling
private static void testUnsafeDeserializationWithWrapper() throws Exception {
JacksonTest.withSocket(string -> {
ObjectMapper mapper = new ObjectMapper();
mapper.readValue(string, Task.class); // $unsafeDeserialization
});
}
}
class SaferPersonDeserialization {
// GOOD: Despite enabled polymorphic type handling, this is safe because ObjectMapper
// has a validator
private static void testSafeDeserializationWithValidator() throws Exception {
JacksonTest.withSocket(string -> {
PolymorphicTypeValidator ptv =
BasicPolymorphicTypeValidator.builder()
.allowIfSubType("only.allowed.package")
.build();
ObjectMapper mapper = new ObjectMapper();
mapper.setPolymorphicTypeValidator(ptv);
mapper.readValue(string, Person.class);
});
}
// GOOD: Despite enabled polymorphic type handling, this is safe because ObjectMapper
// has a validator
private static void testSafeDeserializationWithValidatorAndBuilder() throws Exception {
JacksonTest.withSocket(string -> {
PolymorphicTypeValidator ptv =
BasicPolymorphicTypeValidator.builder()
.allowIfSubType("only.allowed.package")
.build();
ObjectMapper mapper = JsonMapper.builder()
.polymorphicTypeValidator(ptv)
.build();
mapper.readValue(string, Person.class);
});
}
}
class UnsafeCatDeserialization {
// BAD: deserializing untrusted input while polymorphic type handling is on
private static void testUnsafeDeserialization() throws Exception {
JacksonTest.withSocket(string -> {
ObjectMapper mapper = new ObjectMapper();
mapper.enableDefaultTyping(); // this enables polymorphic type handling
mapper.readValue(string, Cat.class); // $unsafeDeserialization
});
}
// BAD: deserializing untrusted input while polymorphic type handling is on
private static void testUnsafeDeserializationWithObjectMapperReadValues() throws Exception {
JacksonTest.withSocket(string -> {
ObjectMapper mapper = new ObjectMapper();
mapper.enableDefaultTyping();
mapper.readValues(new JsonFactory().createParser(string), Cat.class).readAll(); // $unsafeDeserialization
});
}
// BAD: deserializing untrusted input while polymorphic type handling is on
private static void testUnsafeDeserializationWithObjectMapperTreeToValue() throws Exception {
JacksonTest.withSocket(string -> {
ObjectMapper mapper = new ObjectMapper();
mapper.enableDefaultTyping();
mapper.treeToValue(mapper.readTree(string), Cat.class); // $unsafeDeserialization
});
}
// BAD: an attacker can control both data and type of deserialized object
private static void testUnsafeDeserializationWithUnsafeClass() throws Exception {
JacksonTest.withSocket(input -> {
String[] parts = input.split(";");
String data = parts[0];
String type = parts[1];
Class clazz = Class.forName(type);
ObjectMapper mapper = new ObjectMapper();
mapper.readValue(data, clazz); // $unsafeDeserialization
});
}
// BAD: an attacker can control both data and type of deserialized object
private static void testUnsafeDeserializationWithUnsafeClassAndCustomTypeResolver() throws Exception {
JacksonTest.withSocket(input -> {
String[] parts = input.split(";");
String data = parts[0];
String type = parts[1];
ObjectMapper mapper = new ObjectMapper();
mapper.readValue(data, resolveImpl(type, mapper)); // $unsafeDeserialization
});
}
private static JavaType resolveImpl(String type, ObjectMapper mapper) throws Exception {
return mapper.constructType(Class.forName(type));
}
}
class SaferCatDeserialization {
// GOOD: Despite enabled polymorphic type handling, this is safe because ObjectMapper
// has a validator
private static void testUnsafeDeserialization() throws Exception {
JacksonTest.withSocket(string -> {
PolymorphicTypeValidator ptv =
BasicPolymorphicTypeValidator.builder()
.allowIfSubType("only.allowed.pachage")
.build();
ObjectMapper mapper = JsonMapper.builder().polymorphicTypeValidator(ptv).build();
mapper.enableDefaultTyping(); // this enables polymorphic type handling
mapper.readValue(string, Cat.class);
});
}
}

View File

@@ -19,7 +19,7 @@ public class TestMessageBodyReader implements MessageBodyReader<Object> {
public Object readFrom(Class<Object> type, Type genericType, Annotation[] annotations, MediaType mediaType,
MultivaluedMap<String, String> httpHeaders, InputStream entityStream) throws IOException {
try {
return new ObjectInputStream(entityStream).readObject();
return new ObjectInputStream(entityStream).readObject(); // $unsafeDeserialization
} catch (ClassNotFoundException e) {
e.printStackTrace();
}

View File

@@ -1,229 +0,0 @@
edges
| A.java:13:31:13:51 | getInputStream(...) : InputStream | A.java:14:50:14:60 | inputStream : InputStream |
| A.java:13:31:13:51 | getInputStream(...) : InputStream | A.java:15:12:15:13 | in |
| A.java:14:28:14:61 | new ObjectInputStream(...) : ObjectInputStream | A.java:15:12:15:13 | in |
| A.java:14:50:14:60 | inputStream : InputStream | A.java:14:28:14:61 | new ObjectInputStream(...) : ObjectInputStream |
| A.java:19:31:19:51 | getInputStream(...) : InputStream | A.java:20:50:20:60 | inputStream : InputStream |
| A.java:19:31:19:51 | getInputStream(...) : InputStream | A.java:21:12:21:13 | in |
| A.java:20:28:20:61 | new ObjectInputStream(...) : ObjectInputStream | A.java:21:12:21:13 | in |
| A.java:20:50:20:60 | inputStream : InputStream | A.java:20:28:20:61 | new ObjectInputStream(...) : ObjectInputStream |
| A.java:25:31:25:51 | getInputStream(...) : InputStream | A.java:26:35:26:45 | inputStream : InputStream |
| A.java:26:20:26:46 | new XMLDecoder(...) : XMLDecoder | A.java:27:12:27:12 | d |
| A.java:26:35:26:45 | inputStream : InputStream | A.java:26:20:26:46 | new XMLDecoder(...) : XMLDecoder |
| A.java:32:31:32:51 | getInputStream(...) : InputStream | A.java:33:43:33:53 | inputStream : InputStream |
| A.java:33:21:33:54 | new InputStreamReader(...) : InputStreamReader | A.java:34:23:34:28 | reader |
| A.java:33:43:33:53 | inputStream : InputStream | A.java:33:21:33:54 | new InputStreamReader(...) : InputStreamReader |
| A.java:39:19:39:50 | new Input(...) : Input | A.java:40:28:40:32 | input |
| A.java:39:19:39:50 | new Input(...) : Input | A.java:41:34:41:38 | input |
| A.java:39:19:39:50 | new Input(...) : Input | A.java:42:40:42:44 | input |
| A.java:39:29:39:49 | getInputStream(...) : InputStream | A.java:39:19:39:50 | new Input(...) : Input |
| A.java:60:25:60:45 | getInputStream(...) : InputStream | A.java:61:26:61:30 | input |
| A.java:60:25:60:45 | getInputStream(...) : InputStream | A.java:62:30:62:34 | input |
| A.java:60:25:60:45 | getInputStream(...) : InputStream | A.java:63:50:63:54 | input : InputStream |
| A.java:60:25:60:45 | getInputStream(...) : InputStream | A.java:64:24:64:28 | input |
| A.java:60:25:60:45 | getInputStream(...) : InputStream | A.java:65:46:65:50 | input : InputStream |
| A.java:63:50:63:54 | input : InputStream | A.java:63:28:63:55 | new InputStreamReader(...) |
| A.java:65:46:65:50 | input : InputStream | A.java:65:24:65:51 | new InputStreamReader(...) |
| A.java:70:25:70:45 | getInputStream(...) : InputStream | A.java:71:26:71:30 | input |
| A.java:70:25:70:45 | getInputStream(...) : InputStream | A.java:72:30:72:34 | input |
| A.java:70:25:70:45 | getInputStream(...) : InputStream | A.java:73:50:73:54 | input : InputStream |
| A.java:70:25:70:45 | getInputStream(...) : InputStream | A.java:74:24:74:28 | input |
| A.java:70:25:70:45 | getInputStream(...) : InputStream | A.java:75:46:75:50 | input : InputStream |
| A.java:73:50:73:54 | input : InputStream | A.java:73:28:73:55 | new InputStreamReader(...) |
| A.java:75:46:75:50 | input : InputStream | A.java:75:24:75:51 | new InputStreamReader(...) |
| A.java:90:25:90:45 | getInputStream(...) : InputStream | A.java:91:26:91:30 | input |
| A.java:90:25:90:45 | getInputStream(...) : InputStream | A.java:92:30:92:34 | input |
| A.java:90:25:90:45 | getInputStream(...) : InputStream | A.java:93:50:93:54 | input : InputStream |
| A.java:90:25:90:45 | getInputStream(...) : InputStream | A.java:94:24:94:28 | input |
| A.java:90:25:90:45 | getInputStream(...) : InputStream | A.java:95:46:95:50 | input : InputStream |
| A.java:93:50:93:54 | input : InputStream | A.java:93:28:93:55 | new InputStreamReader(...) |
| A.java:95:46:95:50 | input : InputStream | A.java:95:24:95:51 | new InputStreamReader(...) |
| B.java:7:31:7:51 | getInputStream(...) : InputStream | B.java:8:29:8:39 | inputStream |
| B.java:12:31:12:51 | getInputStream(...) : InputStream | B.java:14:5:14:15 | inputStream : InputStream |
| B.java:14:5:14:15 | inputStream : InputStream | B.java:14:22:14:26 | bytes [post update] : byte[] |
| B.java:14:22:14:26 | bytes [post update] : byte[] | B.java:15:23:15:27 | bytes |
| B.java:19:31:19:51 | getInputStream(...) : InputStream | B.java:21:5:21:15 | inputStream : InputStream |
| B.java:21:5:21:15 | inputStream : InputStream | B.java:21:22:21:26 | bytes [post update] : byte[] |
| B.java:21:22:21:26 | bytes [post update] : byte[] | B.java:23:29:23:29 | s |
| B.java:27:31:27:51 | getInputStream(...) : InputStream | B.java:29:5:29:15 | inputStream : InputStream |
| B.java:29:5:29:15 | inputStream : InputStream | B.java:29:22:29:26 | bytes [post update] : byte[] |
| B.java:29:22:29:26 | bytes [post update] : byte[] | B.java:31:23:31:23 | s |
| C.java:23:17:23:44 | getParameter(...) : String | C.java:24:13:24:16 | data |
| C.java:23:17:23:44 | getParameter(...) : String | C.java:25:19:25:22 | data |
| C.java:23:17:23:44 | getParameter(...) : String | C.java:26:25:26:28 | data |
| C.java:23:17:23:44 | getParameter(...) : String | C.java:27:17:27:20 | data |
| C.java:23:17:23:44 | getParameter(...) : String | C.java:30:19:30:22 | data |
| C.java:23:17:23:44 | getParameter(...) : String | C.java:31:25:31:28 | data |
| C.java:23:17:23:44 | getParameter(...) : String | C.java:32:31:32:34 | data |
| C.java:23:17:23:44 | getParameter(...) : String | C.java:33:23:33:26 | data |
| C.java:38:17:38:44 | getParameter(...) : String | C.java:43:25:43:28 | data |
| C.java:38:17:38:44 | getParameter(...) : String | C.java:46:3:46:4 | jr |
| C.java:51:17:51:44 | getParameter(...) : String | C.java:53:3:53:3 | r |
| C.java:51:17:51:44 | getParameter(...) : String | C.java:54:3:54:3 | r |
| C.java:51:17:51:44 | getParameter(...) : String | C.java:55:3:55:3 | r |
| C.java:60:18:60:45 | getParameter(...) : String | C.java:61:55:61:59 | bytes : byte[] |
| C.java:60:18:60:45 | getParameter(...) : String | C.java:63:3:63:14 | hessianInput |
| C.java:60:18:60:45 | getParameter(...) : String | C.java:64:3:64:14 | hessianInput |
| C.java:61:30:61:60 | new ByteArrayInputStream(...) : ByteArrayInputStream | C.java:63:3:63:14 | hessianInput |
| C.java:61:30:61:60 | new ByteArrayInputStream(...) : ByteArrayInputStream | C.java:64:3:64:14 | hessianInput |
| C.java:61:55:61:59 | bytes : byte[] | C.java:61:30:61:60 | new ByteArrayInputStream(...) : ByteArrayInputStream |
| C.java:69:18:69:45 | getParameter(...) : String | C.java:70:55:70:59 | bytes : byte[] |
| C.java:69:18:69:45 | getParameter(...) : String | C.java:72:3:72:14 | hessianInput |
| C.java:69:18:69:45 | getParameter(...) : String | C.java:73:3:73:14 | hessianInput |
| C.java:70:30:70:60 | new ByteArrayInputStream(...) : ByteArrayInputStream | C.java:72:3:72:14 | hessianInput |
| C.java:70:30:70:60 | new ByteArrayInputStream(...) : ByteArrayInputStream | C.java:73:3:73:14 | hessianInput |
| C.java:70:55:70:59 | bytes : byte[] | C.java:70:30:70:60 | new ByteArrayInputStream(...) : ByteArrayInputStream |
| C.java:79:43:79:70 | getParameter(...) : String | C.java:79:26:79:71 | new StringReader(...) |
| C.java:84:27:84:54 | getParameter(...) : String | C.java:85:54:85:67 | serializedData : byte[] |
| C.java:84:27:84:54 | getParameter(...) : String | C.java:87:3:87:13 | burlapInput |
| C.java:84:27:84:54 | getParameter(...) : String | C.java:91:3:91:14 | burlapInput1 |
| C.java:85:29:85:68 | new ByteArrayInputStream(...) : ByteArrayInputStream | C.java:87:3:87:13 | burlapInput |
| C.java:85:29:85:68 | new ByteArrayInputStream(...) : ByteArrayInputStream | C.java:91:3:91:14 | burlapInput1 |
| C.java:85:54:85:67 | serializedData : byte[] | C.java:85:29:85:68 | new ByteArrayInputStream(...) : ByteArrayInputStream |
| TestMessageBodyReader.java:20:55:20:78 | entityStream : InputStream | TestMessageBodyReader.java:22:18:22:52 | new ObjectInputStream(...) |
| TestMessageBodyReader.java:20:55:20:78 | entityStream : InputStream | TestMessageBodyReader.java:22:40:22:51 | entityStream : InputStream |
| TestMessageBodyReader.java:22:40:22:51 | entityStream : InputStream | TestMessageBodyReader.java:22:18:22:52 | new ObjectInputStream(...) |
nodes
| A.java:13:31:13:51 | getInputStream(...) : InputStream | semmle.label | getInputStream(...) : InputStream |
| A.java:14:28:14:61 | new ObjectInputStream(...) : ObjectInputStream | semmle.label | new ObjectInputStream(...) : ObjectInputStream |
| A.java:14:50:14:60 | inputStream : InputStream | semmle.label | inputStream : InputStream |
| A.java:15:12:15:13 | in | semmle.label | in |
| A.java:19:31:19:51 | getInputStream(...) : InputStream | semmle.label | getInputStream(...) : InputStream |
| A.java:20:28:20:61 | new ObjectInputStream(...) : ObjectInputStream | semmle.label | new ObjectInputStream(...) : ObjectInputStream |
| A.java:20:50:20:60 | inputStream : InputStream | semmle.label | inputStream : InputStream |
| A.java:21:12:21:13 | in | semmle.label | in |
| A.java:25:31:25:51 | getInputStream(...) : InputStream | semmle.label | getInputStream(...) : InputStream |
| A.java:26:20:26:46 | new XMLDecoder(...) : XMLDecoder | semmle.label | new XMLDecoder(...) : XMLDecoder |
| A.java:26:35:26:45 | inputStream : InputStream | semmle.label | inputStream : InputStream |
| A.java:27:12:27:12 | d | semmle.label | d |
| A.java:32:31:32:51 | getInputStream(...) : InputStream | semmle.label | getInputStream(...) : InputStream |
| A.java:33:21:33:54 | new InputStreamReader(...) : InputStreamReader | semmle.label | new InputStreamReader(...) : InputStreamReader |
| A.java:33:43:33:53 | inputStream : InputStream | semmle.label | inputStream : InputStream |
| A.java:34:23:34:28 | reader | semmle.label | reader |
| A.java:39:19:39:50 | new Input(...) : Input | semmle.label | new Input(...) : Input |
| A.java:39:29:39:49 | getInputStream(...) : InputStream | semmle.label | getInputStream(...) : InputStream |
| A.java:40:28:40:32 | input | semmle.label | input |
| A.java:41:34:41:38 | input | semmle.label | input |
| A.java:42:40:42:44 | input | semmle.label | input |
| A.java:60:25:60:45 | getInputStream(...) : InputStream | semmle.label | getInputStream(...) : InputStream |
| A.java:61:26:61:30 | input | semmle.label | input |
| A.java:62:30:62:34 | input | semmle.label | input |
| A.java:63:28:63:55 | new InputStreamReader(...) | semmle.label | new InputStreamReader(...) |
| A.java:63:50:63:54 | input : InputStream | semmle.label | input : InputStream |
| A.java:64:24:64:28 | input | semmle.label | input |
| A.java:65:24:65:51 | new InputStreamReader(...) | semmle.label | new InputStreamReader(...) |
| A.java:65:46:65:50 | input : InputStream | semmle.label | input : InputStream |
| A.java:70:25:70:45 | getInputStream(...) : InputStream | semmle.label | getInputStream(...) : InputStream |
| A.java:71:26:71:30 | input | semmle.label | input |
| A.java:72:30:72:34 | input | semmle.label | input |
| A.java:73:28:73:55 | new InputStreamReader(...) | semmle.label | new InputStreamReader(...) |
| A.java:73:50:73:54 | input : InputStream | semmle.label | input : InputStream |
| A.java:74:24:74:28 | input | semmle.label | input |
| A.java:75:24:75:51 | new InputStreamReader(...) | semmle.label | new InputStreamReader(...) |
| A.java:75:46:75:50 | input : InputStream | semmle.label | input : InputStream |
| A.java:90:25:90:45 | getInputStream(...) : InputStream | semmle.label | getInputStream(...) : InputStream |
| A.java:91:26:91:30 | input | semmle.label | input |
| A.java:92:30:92:34 | input | semmle.label | input |
| A.java:93:28:93:55 | new InputStreamReader(...) | semmle.label | new InputStreamReader(...) |
| A.java:93:50:93:54 | input : InputStream | semmle.label | input : InputStream |
| A.java:94:24:94:28 | input | semmle.label | input |
| A.java:95:24:95:51 | new InputStreamReader(...) | semmle.label | new InputStreamReader(...) |
| A.java:95:46:95:50 | input : InputStream | semmle.label | input : InputStream |
| B.java:7:31:7:51 | getInputStream(...) : InputStream | semmle.label | getInputStream(...) : InputStream |
| B.java:8:29:8:39 | inputStream | semmle.label | inputStream |
| B.java:12:31:12:51 | getInputStream(...) : InputStream | semmle.label | getInputStream(...) : InputStream |
| B.java:14:5:14:15 | inputStream : InputStream | semmle.label | inputStream : InputStream |
| B.java:14:22:14:26 | bytes [post update] : byte[] | semmle.label | bytes [post update] : byte[] |
| B.java:15:23:15:27 | bytes | semmle.label | bytes |
| B.java:19:31:19:51 | getInputStream(...) : InputStream | semmle.label | getInputStream(...) : InputStream |
| B.java:21:5:21:15 | inputStream : InputStream | semmle.label | inputStream : InputStream |
| B.java:21:22:21:26 | bytes [post update] : byte[] | semmle.label | bytes [post update] : byte[] |
| B.java:23:29:23:29 | s | semmle.label | s |
| B.java:27:31:27:51 | getInputStream(...) : InputStream | semmle.label | getInputStream(...) : InputStream |
| B.java:29:5:29:15 | inputStream : InputStream | semmle.label | inputStream : InputStream |
| B.java:29:22:29:26 | bytes [post update] : byte[] | semmle.label | bytes [post update] : byte[] |
| B.java:31:23:31:23 | s | semmle.label | s |
| C.java:23:17:23:44 | getParameter(...) : String | semmle.label | getParameter(...) : String |
| C.java:24:13:24:16 | data | semmle.label | data |
| C.java:25:19:25:22 | data | semmle.label | data |
| C.java:26:25:26:28 | data | semmle.label | data |
| C.java:27:17:27:20 | data | semmle.label | data |
| C.java:30:19:30:22 | data | semmle.label | data |
| C.java:31:25:31:28 | data | semmle.label | data |
| C.java:32:31:32:34 | data | semmle.label | data |
| C.java:33:23:33:26 | data | semmle.label | data |
| C.java:38:17:38:44 | getParameter(...) : String | semmle.label | getParameter(...) : String |
| C.java:43:25:43:28 | data | semmle.label | data |
| C.java:46:3:46:4 | jr | semmle.label | jr |
| C.java:51:17:51:44 | getParameter(...) : String | semmle.label | getParameter(...) : String |
| C.java:53:3:53:3 | r | semmle.label | r |
| C.java:54:3:54:3 | r | semmle.label | r |
| C.java:55:3:55:3 | r | semmle.label | r |
| C.java:60:18:60:45 | getParameter(...) : String | semmle.label | getParameter(...) : String |
| C.java:61:30:61:60 | new ByteArrayInputStream(...) : ByteArrayInputStream | semmle.label | new ByteArrayInputStream(...) : ByteArrayInputStream |
| C.java:61:55:61:59 | bytes : byte[] | semmle.label | bytes : byte[] |
| C.java:63:3:63:14 | hessianInput | semmle.label | hessianInput |
| C.java:64:3:64:14 | hessianInput | semmle.label | hessianInput |
| C.java:69:18:69:45 | getParameter(...) : String | semmle.label | getParameter(...) : String |
| C.java:70:30:70:60 | new ByteArrayInputStream(...) : ByteArrayInputStream | semmle.label | new ByteArrayInputStream(...) : ByteArrayInputStream |
| C.java:70:55:70:59 | bytes : byte[] | semmle.label | bytes : byte[] |
| C.java:72:3:72:14 | hessianInput | semmle.label | hessianInput |
| C.java:73:3:73:14 | hessianInput | semmle.label | hessianInput |
| C.java:79:26:79:71 | new StringReader(...) | semmle.label | new StringReader(...) |
| C.java:79:43:79:70 | getParameter(...) : String | semmle.label | getParameter(...) : String |
| C.java:84:27:84:54 | getParameter(...) : String | semmle.label | getParameter(...) : String |
| C.java:85:29:85:68 | new ByteArrayInputStream(...) : ByteArrayInputStream | semmle.label | new ByteArrayInputStream(...) : ByteArrayInputStream |
| C.java:85:54:85:67 | serializedData : byte[] | semmle.label | serializedData : byte[] |
| C.java:87:3:87:13 | burlapInput | semmle.label | burlapInput |
| C.java:91:3:91:14 | burlapInput1 | semmle.label | burlapInput1 |
| TestMessageBodyReader.java:20:55:20:78 | entityStream : InputStream | semmle.label | entityStream : InputStream |
| TestMessageBodyReader.java:22:18:22:52 | new ObjectInputStream(...) | semmle.label | new ObjectInputStream(...) |
| TestMessageBodyReader.java:22:40:22:51 | entityStream : InputStream | semmle.label | entityStream : InputStream |
#select
| A.java:15:12:15:26 | readObject(...) | A.java:13:31:13:51 | getInputStream(...) : InputStream | A.java:15:12:15:13 | in | Unsafe deserialization of $@. | A.java:13:31:13:51 | getInputStream(...) | user input |
| A.java:21:12:21:28 | readUnshared(...) | A.java:19:31:19:51 | getInputStream(...) : InputStream | A.java:21:12:21:13 | in | Unsafe deserialization of $@. | A.java:19:31:19:51 | getInputStream(...) | user input |
| A.java:27:12:27:25 | readObject(...) | A.java:25:31:25:51 | getInputStream(...) : InputStream | A.java:27:12:27:12 | d | Unsafe deserialization of $@. | A.java:25:31:25:51 | getInputStream(...) | user input |
| A.java:34:12:34:29 | fromXML(...) | A.java:32:31:32:51 | getInputStream(...) : InputStream | A.java:34:23:34:28 | reader | Unsafe deserialization of $@. | A.java:32:31:32:51 | getInputStream(...) | user input |
| A.java:40:12:40:42 | readObject(...) | A.java:39:29:39:49 | getInputStream(...) : InputStream | A.java:40:28:40:32 | input | Unsafe deserialization of $@. | A.java:39:29:39:49 | getInputStream(...) | user input |
| A.java:41:12:41:48 | readObjectOrNull(...) | A.java:39:29:39:49 | getInputStream(...) : InputStream | A.java:41:34:41:38 | input | Unsafe deserialization of $@. | A.java:39:29:39:49 | getInputStream(...) | user input |
| A.java:42:16:42:45 | readClassAndObject(...) | A.java:39:29:39:49 | getInputStream(...) : InputStream | A.java:42:40:42:44 | input | Unsafe deserialization of $@. | A.java:39:29:39:49 | getInputStream(...) | user input |
| A.java:61:16:61:31 | load(...) | A.java:60:25:60:45 | getInputStream(...) : InputStream | A.java:61:26:61:30 | input | Unsafe deserialization of $@. | A.java:60:25:60:45 | getInputStream(...) | user input |
| A.java:62:17:62:35 | loadAll(...) | A.java:60:25:60:45 | getInputStream(...) : InputStream | A.java:62:30:62:34 | input | Unsafe deserialization of $@. | A.java:60:25:60:45 | getInputStream(...) | user input |
| A.java:63:17:63:56 | parse(...) | A.java:60:25:60:45 | getInputStream(...) : InputStream | A.java:63:28:63:55 | new InputStreamReader(...) | Unsafe deserialization of $@. | A.java:60:25:60:45 | getInputStream(...) | user input |
| A.java:64:12:64:38 | loadAs(...) | A.java:60:25:60:45 | getInputStream(...) : InputStream | A.java:64:24:64:28 | input | Unsafe deserialization of $@. | A.java:60:25:60:45 | getInputStream(...) | user input |
| A.java:65:12:65:61 | loadAs(...) | A.java:60:25:60:45 | getInputStream(...) : InputStream | A.java:65:24:65:51 | new InputStreamReader(...) | Unsafe deserialization of $@. | A.java:60:25:60:45 | getInputStream(...) | user input |
| A.java:71:16:71:31 | load(...) | A.java:70:25:70:45 | getInputStream(...) : InputStream | A.java:71:26:71:30 | input | Unsafe deserialization of $@. | A.java:70:25:70:45 | getInputStream(...) | user input |
| A.java:72:17:72:35 | loadAll(...) | A.java:70:25:70:45 | getInputStream(...) : InputStream | A.java:72:30:72:34 | input | Unsafe deserialization of $@. | A.java:70:25:70:45 | getInputStream(...) | user input |
| A.java:73:17:73:56 | parse(...) | A.java:70:25:70:45 | getInputStream(...) : InputStream | A.java:73:28:73:55 | new InputStreamReader(...) | Unsafe deserialization of $@. | A.java:70:25:70:45 | getInputStream(...) | user input |
| A.java:74:12:74:38 | loadAs(...) | A.java:70:25:70:45 | getInputStream(...) : InputStream | A.java:74:24:74:28 | input | Unsafe deserialization of $@. | A.java:70:25:70:45 | getInputStream(...) | user input |
| A.java:75:12:75:61 | loadAs(...) | A.java:70:25:70:45 | getInputStream(...) : InputStream | A.java:75:24:75:51 | new InputStreamReader(...) | Unsafe deserialization of $@. | A.java:70:25:70:45 | getInputStream(...) | user input |
| A.java:91:16:91:31 | load(...) | A.java:90:25:90:45 | getInputStream(...) : InputStream | A.java:91:26:91:30 | input | Unsafe deserialization of $@. | A.java:90:25:90:45 | getInputStream(...) | user input |
| A.java:92:17:92:35 | loadAll(...) | A.java:90:25:90:45 | getInputStream(...) : InputStream | A.java:92:30:92:34 | input | Unsafe deserialization of $@. | A.java:90:25:90:45 | getInputStream(...) | user input |
| A.java:93:17:93:56 | parse(...) | A.java:90:25:90:45 | getInputStream(...) : InputStream | A.java:93:28:93:55 | new InputStreamReader(...) | Unsafe deserialization of $@. | A.java:90:25:90:45 | getInputStream(...) | user input |
| A.java:94:12:94:38 | loadAs(...) | A.java:90:25:90:45 | getInputStream(...) : InputStream | A.java:94:24:94:28 | input | Unsafe deserialization of $@. | A.java:90:25:90:45 | getInputStream(...) | user input |
| A.java:95:12:95:61 | loadAs(...) | A.java:90:25:90:45 | getInputStream(...) : InputStream | A.java:95:24:95:51 | new InputStreamReader(...) | Unsafe deserialization of $@. | A.java:90:25:90:45 | getInputStream(...) | user input |
| B.java:8:12:8:46 | parseObject(...) | B.java:7:31:7:51 | getInputStream(...) : InputStream | B.java:8:29:8:39 | inputStream | Unsafe deserialization of $@. | B.java:7:31:7:51 | getInputStream(...) | user input |
| B.java:15:12:15:28 | parse(...) | B.java:12:31:12:51 | getInputStream(...) : InputStream | B.java:15:23:15:27 | bytes | Unsafe deserialization of $@. | B.java:12:31:12:51 | getInputStream(...) | user input |
| B.java:23:12:23:30 | parseObject(...) | B.java:19:31:19:51 | getInputStream(...) : InputStream | B.java:23:29:23:29 | s | Unsafe deserialization of $@. | B.java:19:31:19:51 | getInputStream(...) | user input |
| B.java:31:12:31:24 | parse(...) | B.java:27:31:27:51 | getInputStream(...) : InputStream | B.java:31:23:31:23 | s | Unsafe deserialization of $@. | B.java:27:31:27:51 | getInputStream(...) | user input |
| C.java:24:3:24:17 | load(...) | C.java:23:17:23:44 | getParameter(...) : String | C.java:24:13:24:16 | data | Unsafe deserialization of $@. | C.java:23:17:23:44 | getParameter(...) | user input |
| C.java:25:3:25:23 | loadStream(...) | C.java:23:17:23:44 | getParameter(...) : String | C.java:25:19:25:22 | data | Unsafe deserialization of $@. | C.java:23:17:23:44 | getParameter(...) | user input |
| C.java:26:3:26:43 | loadStreamOfType(...) | C.java:23:17:23:44 | getParameter(...) : String | C.java:26:25:26:28 | data | Unsafe deserialization of $@. | C.java:23:17:23:44 | getParameter(...) | user input |
| C.java:27:3:27:35 | loadType(...) | C.java:23:17:23:44 | getParameter(...) : String | C.java:27:17:27:20 | data | Unsafe deserialization of $@. | C.java:23:17:23:44 | getParameter(...) | user input |
| C.java:30:3:30:23 | load(...) | C.java:23:17:23:44 | getParameter(...) : String | C.java:30:19:30:22 | data | Unsafe deserialization of $@. | C.java:23:17:23:44 | getParameter(...) | user input |
| C.java:31:3:31:29 | loadStream(...) | C.java:23:17:23:44 | getParameter(...) : String | C.java:31:25:31:28 | data | Unsafe deserialization of $@. | C.java:23:17:23:44 | getParameter(...) | user input |
| C.java:32:3:32:49 | loadStreamOfType(...) | C.java:23:17:23:44 | getParameter(...) : String | C.java:32:31:32:34 | data | Unsafe deserialization of $@. | C.java:23:17:23:44 | getParameter(...) | user input |
| C.java:33:3:33:41 | loadType(...) | C.java:23:17:23:44 | getParameter(...) : String | C.java:33:23:33:26 | data | Unsafe deserialization of $@. | C.java:23:17:23:44 | getParameter(...) | user input |
| C.java:43:3:43:29 | jsonToJava(...) | C.java:38:17:38:44 | getParameter(...) : String | C.java:43:25:43:28 | data | Unsafe deserialization of $@. | C.java:38:17:38:44 | getParameter(...) | user input |
| C.java:46:3:46:17 | readObject(...) | C.java:38:17:38:44 | getParameter(...) : String | C.java:46:3:46:4 | jr | Unsafe deserialization of $@. | C.java:38:17:38:44 | getParameter(...) | user input |
| C.java:53:3:53:10 | read(...) | C.java:51:17:51:44 | getParameter(...) : String | C.java:53:3:53:3 | r | Unsafe deserialization of $@. | C.java:51:17:51:44 | getParameter(...) | user input |
| C.java:54:3:54:22 | read(...) | C.java:51:17:51:44 | getParameter(...) : String | C.java:54:3:54:3 | r | Unsafe deserialization of $@. | C.java:51:17:51:44 | getParameter(...) | user input |
| C.java:55:3:55:36 | read(...) | C.java:51:17:51:44 | getParameter(...) : String | C.java:55:3:55:3 | r | Unsafe deserialization of $@. | C.java:51:17:51:44 | getParameter(...) | user input |
| C.java:63:3:63:27 | readObject(...) | C.java:60:18:60:45 | getParameter(...) : String | C.java:63:3:63:14 | hessianInput | Unsafe deserialization of $@. | C.java:60:18:60:45 | getParameter(...) | user input |
| C.java:64:3:64:39 | readObject(...) | C.java:60:18:60:45 | getParameter(...) : String | C.java:64:3:64:14 | hessianInput | Unsafe deserialization of $@. | C.java:60:18:60:45 | getParameter(...) | user input |
| C.java:72:3:72:27 | readObject(...) | C.java:69:18:69:45 | getParameter(...) : String | C.java:72:3:72:14 | hessianInput | Unsafe deserialization of $@. | C.java:69:18:69:45 | getParameter(...) | user input |
| C.java:73:3:73:39 | readObject(...) | C.java:69:18:69:45 | getParameter(...) : String | C.java:73:3:73:14 | hessianInput | Unsafe deserialization of $@. | C.java:69:18:69:45 | getParameter(...) | user input |
| C.java:79:3:79:72 | unmarshal(...) | C.java:79:43:79:70 | getParameter(...) : String | C.java:79:26:79:71 | new StringReader(...) | Unsafe deserialization of $@. | C.java:79:43:79:70 | getParameter(...) | user input |
| C.java:87:3:87:26 | readObject(...) | C.java:84:27:84:54 | getParameter(...) : String | C.java:87:3:87:13 | burlapInput | Unsafe deserialization of $@. | C.java:84:27:84:54 | getParameter(...) | user input |
| C.java:91:3:91:27 | readObject(...) | C.java:84:27:84:54 | getParameter(...) : String | C.java:91:3:91:14 | burlapInput1 | Unsafe deserialization of $@. | C.java:84:27:84:54 | getParameter(...) | user input |
| TestMessageBodyReader.java:22:18:22:65 | readObject(...) | TestMessageBodyReader.java:20:55:20:78 | entityStream : InputStream | TestMessageBodyReader.java:22:18:22:52 | new ObjectInputStream(...) | Unsafe deserialization of $@. | TestMessageBodyReader.java:20:55:20:78 | entityStream | user input |

View File

@@ -0,0 +1,18 @@
import java
import semmle.code.java.security.UnsafeDeserializationQuery
import TestUtilities.InlineExpectationsTest
class UnsafeDeserializationTest extends InlineExpectationsTest {
UnsafeDeserializationTest() { this = "UnsafeDeserializationTest" }
override string getARelevantTag() { result = "unsafeDeserialization" }
override predicate hasActualResult(Location location, string element, string tag, string value) {
tag = "unsafeDeserialization" and
exists(DataFlow::Node sink, UnsafeDeserializationConfig conf | conf.hasFlowTo(sink) |
sink.getLocation() = location and
element = sink.toString() and
value = ""
)
}
}

View File

@@ -1 +0,0 @@
Security/CWE/CWE-502/UnsafeDeserialization.ql

View File

@@ -1 +1 @@
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../stubs/snakeyaml-1.21:${testdir}/../../../stubs/xstream-1.4.10:${testdir}/../../../stubs/kryo-4.0.2:${testdir}/../../../stubs/jsr311-api-1.1.1:${testdir}/../../../stubs/fastjson-1.2.74:${testdir}/../../../stubs/springframework-5.3.8:${testdir}/../../../stubs/servlet-api-2.4:${testdir}/../../../stubs/jyaml-1.3:${testdir}/../../../stubs/json-io-4.10.0:${testdir}/../../../stubs/yamlbeans-1.09:${testdir}/../../../stubs/hessian-4.0.38:${testdir}/../../../stubs/castor-1.4.1
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../stubs/snakeyaml-1.21:${testdir}/../../../stubs/xstream-1.4.10:${testdir}/../../../stubs/kryo-4.0.2:${testdir}/../../../stubs/jsr311-api-1.1.1:${testdir}/../../../stubs/fastjson-1.2.74:${testdir}/../../../stubs/springframework-5.3.8:${testdir}/../../../stubs/servlet-api-2.4:${testdir}/../../../stubs/jyaml-1.3:${testdir}/../../../stubs/json-io-4.10.0:${testdir}/../../../stubs/yamlbeans-1.09:${testdir}/../../../stubs/hessian-4.0.38:${testdir}/../../../stubs/castor-1.4.1:${testdir}/../../../stubs/jackson-databind-2.10