Merge pull request #5881 from haby0/java/UnsafeDeserialization

Java: CWE-502 Add UnsafeDeserialization sinks
This commit is contained in:
Anders Schack-Mulligen
2021-06-17 12:36:34 +02:00
committed by GitHub
39 changed files with 2073 additions and 3 deletions

View File

@@ -0,0 +1,20 @@
/**
* Provides classes and predicates for working with the Castor framework.
*/
import java
/**
* The class `org.exolab.castor.xml.Unmarshaller`.
*/
class CastorUnmarshaller extends RefType {
CastorUnmarshaller() { this.hasQualifiedName("org.exolab.castor.xml", "Unmarshaller") }
}
/** A method with the name `unmarshal` declared in `org.exolab.castor.xml.Unmarshaller`. */
class CastorUnmarshalMethod extends Method {
CastorUnmarshalMethod() {
this.getDeclaringType() instanceof CastorUnmarshaller and
this.getName() = "unmarshal"
}
}

View File

@@ -0,0 +1,49 @@
/**
* Provides classes and predicates for working with the HessianBurlap framework.
*/
import java
/**
* The classes `[com.alibaba.]com.caucho.hessian.io.AbstractHessianInput` or `[com.alibaba.]com.caucho.hessian.io.Hessian2StreamingInput`.
*/
class UnsafeHessianInput extends RefType {
UnsafeHessianInput() {
this.hasQualifiedName(["com.caucho.hessian.io", "com.alibaba.com.caucho.hessian.io"],
["AbstractHessianInput", "Hessian2StreamingInput"])
}
}
/**
* A AbstractHessianInput or Hessian2StreamingInput subclass readObject method.
* This is either `AbstractHessianInput.readObject` or `Hessian2StreamingInput.readObject`.
*/
class UnsafeHessianInputReadObjectMethod extends Method {
UnsafeHessianInputReadObjectMethod() {
this.getDeclaringType().getASupertype*() instanceof UnsafeHessianInput and
this.getName() = "readObject"
}
}
/**
* The class `com.caucho.burlap.io.BurlapInput`.
*/
class BurlapInput extends RefType {
BurlapInput() { this.hasQualifiedName("com.caucho.burlap.io", "BurlapInput") }
}
/** A method with the name `readObject` declared in `com.caucho.burlap.io.BurlapInput`. */
class BurlapInputReadObjectMethod extends Method {
BurlapInputReadObjectMethod() {
this.getDeclaringType() instanceof BurlapInput and
this.getName() = "readObject"
}
}
/** A method with the name `init` declared in `com.caucho.burlap.io.BurlapInput`. */
class BurlapInputInitMethod extends Method {
BurlapInputInitMethod() {
this.getDeclaringType() instanceof BurlapInput and
this.getName() = "init"
}
}

View File

@@ -0,0 +1,22 @@
/**
* Provides classes and predicates for working with the JYaml framework.
*/
import java
/**
* The class `org.ho.yaml.Yaml` or `org.ho.yaml.YamlConfig`.
*/
class JYamlLoader extends RefType {
JYamlLoader() { this.hasQualifiedName("org.ho.yaml", ["Yaml", "YamlConfig"]) }
}
/**
* A JYaml unsafe load method, declared on either `Yaml` or `YamlConfig`.
*/
class JYamlLoaderUnsafeLoadMethod extends Method {
JYamlLoaderUnsafeLoadMethod() {
this.getDeclaringType() instanceof JYamlLoader and
this.getName() in ["load", "loadType", "loadStream", "loadStreamOfType"]
}
}

View File

@@ -0,0 +1,67 @@
/**
* Provides classes and predicates for working with the Json-io framework.
*/
import java
import semmle.code.java.Maps
import semmle.code.java.dataflow.DataFlow
import semmle.code.java.dataflow.DataFlow2
/**
* The class `com.cedarsoftware.util.io.JsonReader`.
*/
class JsonIoJsonReader extends RefType {
JsonIoJsonReader() { this.hasQualifiedName("com.cedarsoftware.util.io", "JsonReader") }
}
/** A method with the name `jsonToJava` declared in `com.cedarsoftware.util.io.JsonReader`. */
class JsonIoJsonToJavaMethod extends Method {
JsonIoJsonToJavaMethod() {
this.getDeclaringType() instanceof JsonIoJsonReader and
this.getName() = "jsonToJava"
}
}
/** A method with the name `readObject` declared in `com.cedarsoftware.util.io.JsonReader`. */
class JsonIoReadObjectMethod extends Method {
JsonIoReadObjectMethod() {
this.getDeclaringType() instanceof JsonIoJsonReader and
this.getName() = "readObject"
}
}
/**
* A call to `Map.put` method, set the value of the `USE_MAPS` key to `true`.
*/
class JsonIoUseMapsSetter extends MethodAccess {
JsonIoUseMapsSetter() {
this.getMethod().getDeclaringType().getASourceSupertype*() instanceof MapType and
this.getMethod().hasName("put") and
this.getArgument(0).(CompileTimeConstantExpr).getStringValue() = "USE_MAPS" and
this.getArgument(1).(CompileTimeConstantExpr).getBooleanValue() = true
}
}
/** A data flow configuration tracing flow from JsonIo safe settings. */
class SafeJsonIoConfig extends DataFlow2::Configuration {
SafeJsonIoConfig() { this = "UnsafeDeserialization::SafeJsonIoConfig" }
override predicate isSource(DataFlow::Node src) {
exists(MethodAccess ma |
ma instanceof JsonIoUseMapsSetter and
src.asExpr() = ma.getQualifier()
)
}
override predicate isSink(DataFlow::Node sink) {
exists(MethodAccess ma |
ma.getMethod() instanceof JsonIoJsonToJavaMethod and
sink.asExpr() = ma.getArgument(1)
)
or
exists(ClassInstanceExpr cie |
cie.getConstructor().getDeclaringType() instanceof JsonIoJsonReader and
sink.asExpr() = cie.getArgument(1)
)
}
}

View File

@@ -0,0 +1,20 @@
/**
* Provides classes and predicates for working with the YamlBeans framework.
*/
import java
/**
* The class `com.esotericsoftware.yamlbeans.YamlReader`.
*/
class YamlBeansReader extends RefType {
YamlBeansReader() { this.hasQualifiedName("com.esotericsoftware.yamlbeans", "YamlReader") }
}
/** A method with the name `read` declared in `com.esotericsoftware.yamlbeans.YamlReader`. */
class YamlBeansReaderReadMethod extends Method {
YamlBeansReaderReadMethod() {
this.getDeclaringType() instanceof YamlBeansReader and
this.getName() = "read"
}
}

View File

@@ -2,6 +2,11 @@ import semmle.code.java.frameworks.Kryo
import semmle.code.java.frameworks.XStream
import semmle.code.java.frameworks.SnakeYaml
import semmle.code.java.frameworks.FastJson
import semmle.code.java.frameworks.JYaml
import semmle.code.java.frameworks.JsonIo
import semmle.code.java.frameworks.YamlBeans
import semmle.code.java.frameworks.HessianBurlap
import semmle.code.java.frameworks.Castor
import semmle.code.java.frameworks.apache.Lang
class ObjectInputStreamReadObjectMethod extends Method {
@@ -140,6 +145,23 @@ predicate unsafeDeserialization(MethodAccess ma, Expr sink) {
ma.getMethod() instanceof FastJsonParseMethod and
not fastJsonLooksSafe() and
sink = ma.getArgument(0)
or
ma.getMethod() instanceof JYamlLoaderUnsafeLoadMethod and
sink = ma.getArgument(0)
or
ma.getMethod() instanceof JsonIoJsonToJavaMethod and
sink = ma.getArgument(0)
or
ma.getMethod() instanceof JsonIoReadObjectMethod and
sink = ma.getQualifier()
or
ma.getMethod() instanceof YamlBeansReaderReadMethod and sink = ma.getQualifier()
or
ma.getMethod() instanceof UnsafeHessianInputReadObjectMethod and sink = ma.getQualifier()
or
ma.getMethod() instanceof CastorUnmarshalMethod and sink = ma.getAnArgument()
or
ma.getMethod() instanceof BurlapInputReadObjectMethod and sink = ma.getQualifier()
)
}