Skip to content

Commit a17c812

Browse files
authored
Merge pull request github#13358 from jorgectf/jorgectf/deserialization-lookahead
Java: Model `SerialKiller`
2 parents 56a5a57 + 55280e5 commit a17c812

File tree

5 files changed

+50
-4
lines changed

5 files changed

+50
-4
lines changed

java/ql/lib/semmle/code/java/security/UnsafeDeserializationQuery.qll

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,20 @@ private class ObjectInputStreamReadObjectMethod extends Method {
2828
}
2929
}
3030

31+
/**
32+
* A type extending `ObjectInputStream` that makes it safe to deserialize untrusted data.
33+
*
34+
* * See https://commons.apache.org/proper/commons-io/javadocs/api-2.5/org/apache/commons/io/serialization/ValidatingObjectInputStream.html
35+
* * See https://github.com/ikkisoft/SerialKiller
36+
*/
37+
private class SafeObjectInputStreamType extends RefType {
38+
SafeObjectInputStreamType() {
39+
this.getASourceSupertype*()
40+
.hasQualifiedName("org.apache.commons.io.serialization", "ValidatingObjectInputStream") or
41+
this.getASourceSupertype*().hasQualifiedName("org.nibblesec.tools", "SerialKiller")
42+
}
43+
}
44+
3145
private class XmlDecoderReadObjectMethod extends Method {
3246
XmlDecoderReadObjectMethod() {
3347
this.getDeclaringType().hasQualifiedName("java.beans", "XMLDecoder") and
@@ -135,9 +149,7 @@ predicate unsafeDeserialization(MethodAccess ma, Expr sink) {
135149
sink = ma.getQualifier() and
136150
not exists(DataFlow::ExprNode node |
137151
node.getExpr() = sink and
138-
node.getTypeBound()
139-
.(RefType)
140-
.hasQualifiedName("org.apache.commons.io.serialization", "ValidatingObjectInputStream")
152+
node.getTypeBound() instanceof SafeObjectInputStreamType
141153
)
142154
or
143155
m instanceof XmlDecoderReadObjectMethod and
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
category: minorAnalysis
3+
---
4+
* The query `java/unsafe-deserialization` has been updated to take into account `SerialKiller`, a library used to prevent deserialization of arbitrary classes.

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import org.yaml.snakeyaml.constructor.SafeConstructor;
88
import org.yaml.snakeyaml.constructor.Constructor;
99
import org.yaml.snakeyaml.Yaml;
10+
import org.nibblesec.tools.SerialKiller;
1011

1112
public class A {
1213
public Object deserialize1(Socket sock) throws java.io.IOException, ClassNotFoundException {
@@ -21,6 +22,12 @@ public Object deserialize2(Socket sock) throws java.io.IOException, ClassNotFoun
2122
return in.readUnshared(); // $unsafeDeserialization
2223
}
2324

25+
public Object deserializeWithSerialKiller(Socket sock) throws java.io.IOException, ClassNotFoundException {
26+
InputStream inputStream = sock.getInputStream();
27+
ObjectInputStream in = new SerialKiller(inputStream, "/etc/serialkiller.conf");
28+
return in.readUnshared(); // OK
29+
}
30+
2431
public Object deserialize3(Socket sock) throws java.io.IOException {
2532
InputStream inputStream = sock.getInputStream();
2633
XMLDecoder d = new XMLDecoder(inputStream);
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/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.12:${testdir}/../../../stubs/jackson-core-2.12:${testdir}/../../../stubs/jabsorb-1.3.2:${testdir}/../../../stubs/json-java-20210307:${testdir}/../../../stubs/joddjson-6.0.3:${testdir}/../../../stubs/flexjson-2.1:${testdir}/../../../stubs/gson-2.8.6:${testdir}/../../../stubs/google-android-9.0.0
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.12:${testdir}/../../../stubs/jackson-core-2.12:${testdir}/../../../stubs/jabsorb-1.3.2:${testdir}/../../../stubs/json-java-20210307:${testdir}/../../../stubs/joddjson-6.0.3:${testdir}/../../../stubs/flexjson-2.1:${testdir}/../../../stubs/gson-2.8.6:${testdir}/../../../stubs/google-android-9.0.0:${testdir}/../../../stubs/serialkiller-4.0.0

java/ql/test/stubs/serialkiller-4.0.0/org/nibblesec/tools/SerialKiller.java

Lines changed: 23 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)