Merge pull request #5508 from edvraa/deserializers

deserialization sinks
This commit is contained in:
Tom Hvitved
2021-08-17 11:41:52 +02:00
committed by GitHub
35 changed files with 2009 additions and 85 deletions

View File

@@ -27,6 +27,17 @@ it may be necessary to use a different deserialization framework.</p>
<sample src="UnsafeDeserializationUntrustedInputGood.cs" />
<p>In the following example potentially untrusted stream and type is deserialized using a
<code>DataContractJsonSerializer</code> which is known to be vulnerable with user supplied types.</p>
<sample src="UnsafeDeserializationUntrustedInputTypeBad.cs" />
<p>To fix this specific vulnerability, we are using hardcoded
Plain Old CLR Object (<a href="https://en.wikipedia.org/wiki/Plain_old_CLR_object">POCO</a>) type. In other cases,
it may be necessary to use a different deserialization framework.</p>
<sample src="UnsafeDeserializationUntrustedInputTypeGood.cs" />
</example>
<references>

View File

@@ -15,7 +15,46 @@ import csharp
import semmle.code.csharp.security.dataflow.UnsafeDeserializationQuery
import DataFlow::PathGraph
from TaintTrackingConfig config, DataFlow::PathNode source, DataFlow::PathNode sink
where config.hasFlowPath(source, sink)
select sink.getNode(), source, sink, "$@ flows to unsafe deserializer.", source.getNode(),
"User-provided data"
from DataFlow::PathNode userInput, DataFlow::PathNode deserializeCallArg
where
exists(TaintToObjectMethodTrackingConfig taintTracking |
// all flows from user input to deserialization with weak and strong type serializers
taintTracking.hasFlowPath(userInput, deserializeCallArg)
) and
// intersect with strong types, but user controlled or weak types deserialization usages
(
exists(
DataFlow::Node weakTypeCreation, DataFlow::Node weakTypeUsage,
WeakTypeCreationToUsageTrackingConfig weakTypeDeserializerTracking, MethodCall mc
|
weakTypeDeserializerTracking.hasFlow(weakTypeCreation, weakTypeUsage) and
mc.getQualifier() = weakTypeUsage.asExpr() and
mc.getAnArgument() = deserializeCallArg.getNode().asExpr()
)
or
exists(
TaintToObjectTypeTrackingConfig userControlledTypeTracking, DataFlow::Node taintedTypeUsage,
DataFlow::Node userInput2, MethodCall mc
|
userControlledTypeTracking.hasFlow(userInput2, taintedTypeUsage) and
mc.getQualifier() = taintedTypeUsage.asExpr() and
mc.getAnArgument() = deserializeCallArg.getNode().asExpr()
)
)
or
// no type check needed - straightforward taint -> sink
exists(TaintToConstructorOrStaticMethodTrackingConfig taintTracking2 |
taintTracking2.hasFlowPath(userInput, deserializeCallArg)
)
or
// JsonConvert static method call, but with additional unsafe typename tracking
exists(
JsonConvertTrackingConfig taintTrackingJsonConvert, TypeNameTrackingConfig typenameTracking,
DataFlow::Node settingsCallArg
|
taintTrackingJsonConvert.hasFlowPath(userInput, deserializeCallArg) and
typenameTracking.hasFlow(_, settingsCallArg) and
deserializeCallArg.getNode().asExpr().getParent() = settingsCallArg.asExpr().getParent()
)
select deserializeCallArg, userInput, deserializeCallArg, "$@ flows to unsafe deserializer.",
userInput, "User-provided data"

View File

@@ -6,7 +6,7 @@ class Good
public static object Deserialize(TextBox textBox)
{
JavaScriptSerializer sr = new JavaScriptSerializer();
// GOOD
// GOOD: no unsafe type resolver
return sr.DeserializeObject(textBox.Text);
}
}

View File

@@ -0,0 +1,13 @@
using System.Runtime.Serialization.Json;
using System.IO;
using System;
class BadDataContractJsonSerializer
{
public static object Deserialize(string type, Stream s)
{
// BAD: stream and type are potentially untrusted
var ds = new DataContractJsonSerializer(Type.GetType(type));
return ds.ReadObject(s);
}
}

View File

@@ -0,0 +1,20 @@
using System.Runtime.Serialization.Json;
using System.IO;
using System;
class Poco
{
public int Count;
public string Comment;
}
class GoodDataContractJsonSerializer
{
public static Poco Deserialize(Stream s)
{
// GOOD: while stream is potentially untrusted, the instantiated type is hardcoded
var ds = new DataContractJsonSerializer(typeof(Poco));
return (Poco)ds.ReadObject(s);
}
}

View File

@@ -17,6 +17,19 @@ module JsonNET {
JsonClass() { this.getParent() instanceof JsonNETNamespace }
}
/** Newtonsoft.Json.TypeNameHandling enum */
class TypeNameHandlingEnum extends Enum {
TypeNameHandlingEnum() {
this.getParent() instanceof JsonNETNamespace and
this.hasName("TypeNameHandling")
}
}
/** Newtonsoft.Json.JsonSerializerSettings class */
class JsonSerializerSettingsClass extends JsonClass {
JsonSerializerSettingsClass() { this.hasName("JsonSerializerSettings") }
}
/** The class `Newtonsoft.Json.JsonConvert`. */
class JsonConvertClass extends JsonClass, LibraryTypeDataFlow {
JsonConvertClass() { this.hasName("JsonConvert") }

View File

@@ -4,8 +4,9 @@
*/
import csharp
private import semmle.code.csharp.security.dataflow.flowsources.Remote
private import semmle.code.csharp.serialization.Deserializers
private import semmle.code.csharp.dataflow.TaintTracking2
private import semmle.code.csharp.security.dataflow.flowsources.Remote
/**
* A data flow source for unsafe deserialization vulnerabilities.
@@ -17,63 +18,886 @@ abstract class Source extends DataFlow::Node { }
*/
abstract class Sink extends DataFlow::Node { }
/**
* A data flow sink for unsafe deserialization vulnerabilities to an instance method.
*/
abstract private class InstanceMethodSink extends Sink {
InstanceMethodSink() {
not exists(
SafeConstructorTrackingConfig safeConstructorTracking, DataFlow::Node safeTypeUsage,
MethodCall mc
|
safeConstructorTracking.hasFlow(_, safeTypeUsage) and
mc.getQualifier() = safeTypeUsage.asExpr() and
mc.getAnArgument() = this.asExpr()
)
}
}
/**
* A data flow sink for unsafe deserialization vulnerabilities to a static method or constructor call.
*/
abstract private class ConstructorOrStaticMethodSink extends Sink { }
/**
* A sanitizer for unsafe deserialization vulnerabilities.
*/
abstract class Sanitizer extends DataFlow::Node { }
/**
* A taint-tracking configuration for reasoning about unsafe deserialization.
*/
class TaintTrackingConfig extends TaintTracking::Configuration {
TaintTrackingConfig() { this = "UnsafeDeserialization" }
override predicate isSource(DataFlow::Node source) { source instanceof Source }
override predicate isSink(DataFlow::Node sink) { sink instanceof Sink }
override predicate isSanitizer(DataFlow::Node node) { node instanceof Sanitizer }
}
private class RemoteSource extends Source {
RemoteSource() { this instanceof RemoteFlowSource }
}
/** A call to an unsafe deserializer. */
private class UnsafeDeserializerSink extends Sink {
UnsafeDeserializerSink() {
exists(Call c |
this.asExpr() = c.getAnArgument() and
c.getTarget() instanceof UnsafeDeserializer
)
}
}
/**
* User input to object method call deserialization flow tracking.
*/
class TaintToObjectMethodTrackingConfig extends TaintTracking::Configuration {
TaintToObjectMethodTrackingConfig() { this = "TaintToObjectMethodTrackingConfig" }
private class JavaScriptSerializerClass extends Class {
JavaScriptSerializerClass() {
this.hasQualifiedName("System.Web.Script.Serialization.JavaScriptSerializer")
}
override predicate isSource(DataFlow::Node source) { source instanceof Source }
override predicate isSink(DataFlow::Node sink) { sink instanceof InstanceMethodSink }
override predicate isSanitizer(DataFlow::Node node) { node instanceof Sanitizer }
}
/**
* An unsafe use of a JavaScript deserializer. That is, a use with a custom type-resolver
* (constructor parameter).
* User input to `JsonConvert` call deserialization flow tracking.
*/
private class JavaScriptSerializerSink extends Sink {
JavaScriptSerializerSink() {
exists(ObjectCreation oc |
oc.getTarget().getDeclaringType() instanceof JavaScriptSerializerClass and
oc.getTarget().getNumberOfParameters() > 0 and
exists(MethodCall mc, Method m |
m = mc.getTarget() and
m.getDeclaringType() instanceof JavaScriptSerializerClass and
(
m.hasName("Deserialize") or
m.hasName("DeserializeObject")
) and
this.asExpr() = mc.getAnArgument() and
DataFlow::localFlow(DataFlow::exprNode(oc), DataFlow::exprNode(mc.getQualifier()))
class JsonConvertTrackingConfig extends TaintTracking::Configuration {
JsonConvertTrackingConfig() { this = "JsonConvertTrackingConfig" }
override predicate isSource(DataFlow::Node source) { source instanceof Source }
override predicate isSink(DataFlow::Node sink) {
sink instanceof NewtonsoftJsonConvertDeserializeObjectMethodSink
}
override predicate isSanitizer(DataFlow::Node node) { node instanceof Sanitizer }
}
/**
* Tracks unsafe `TypeNameHandling` setting to `JsonConvert` call
*/
class TypeNameTrackingConfig extends DataFlow::Configuration {
TypeNameTrackingConfig() { this = "TypeNameTrackingConfig" }
override predicate isSource(DataFlow::Node source) {
(
source.asExpr() instanceof MemberConstantAccess and
source.getType() instanceof TypeNameHandlingEnum
or
source.asExpr() instanceof IntegerLiteral
) and
source.asExpr().hasValue() and
not source.asExpr().getValue() = "0"
}
override predicate isSink(DataFlow::Node sink) {
exists(MethodCall mc, Method m, Expr expr |
m = mc.getTarget() and
(
not mc.getArgument(0).hasValue() and
m instanceof NewtonsoftJsonConvertClassDeserializeObjectMethod
) and
expr = mc.getAnArgument() and
sink.asExpr() = expr and
expr.getType() instanceof JsonSerializerSettingsClass
)
}
override predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) {
node1.asExpr() instanceof IntegerLiteral and
node2.asExpr().(CastExpr).getExpr() = node1.asExpr()
or
node1.getType() instanceof TypeNameHandlingEnum and
exists(PropertyWrite pw, Property p, Assignment a |
a.getLValue() = pw and
pw.getProperty() = p and
p.getDeclaringType() instanceof JsonSerializerSettingsClass and
p.hasName("TypeNameHandling") and
(
node1.asExpr() = a.getRValue() and
node2.asExpr() = pw.getQualifier()
or
exists(ObjectInitializer oi |
node1.asExpr() = oi.getAMemberInitializer().getRValue() and
node2.asExpr() = oi
)
)
)
}
}
/**
* User input to static method or constructor call deserialization flow tracking.
*/
class TaintToConstructorOrStaticMethodTrackingConfig extends TaintTracking::Configuration {
TaintToConstructorOrStaticMethodTrackingConfig() {
this = "TaintToConstructorOrStaticMethodTrackingConfig"
}
override predicate isSource(DataFlow::Node source) { source instanceof Source }
override predicate isSink(DataFlow::Node sink) { sink instanceof ConstructorOrStaticMethodSink }
override predicate isSanitizer(DataFlow::Node node) { node instanceof Sanitizer }
}
/**
* User input to instance type flow tracking.
*/
class TaintToObjectTypeTrackingConfig extends TaintTracking2::Configuration {
TaintToObjectTypeTrackingConfig() { this = "TaintToObjectTypeTrackingConfig" }
override predicate isSource(DataFlow::Node source) { source instanceof Source }
override predicate isSink(DataFlow::Node sink) {
exists(MethodCall mc |
mc.getTarget() instanceof UnsafeDeserializer and
sink.asExpr() = mc.getQualifier()
)
}
override predicate isAdditionalTaintStep(DataFlow::Node n1, DataFlow::Node n2) {
exists(MethodCall mc, Method m |
m = mc.getTarget() and
m.getDeclaringType().hasQualifiedName("System.Type") and
m.hasName("GetType") and
m.isStatic() and
n1.asExpr() = mc.getArgument(0) and
n2.asExpr() = mc
)
or
exists(ObjectCreation oc |
n1.asExpr() = oc.getAnArgument() and
n2.asExpr() = oc and
oc.getObjectType() instanceof StrongTypeDeserializer
)
}
}
/**
* Unsafe deserializer creation to usage tracking config.
*/
class WeakTypeCreationToUsageTrackingConfig extends TaintTracking2::Configuration {
WeakTypeCreationToUsageTrackingConfig() { this = "DeserializerCreationToUsageTrackingConfig" }
override predicate isSource(DataFlow::Node source) {
exists(ObjectCreation oc |
oc.getObjectType() instanceof WeakTypeDeserializer and
source.asExpr() = oc
)
}
override predicate isSink(DataFlow::Node sink) {
exists(MethodCall mc |
mc.getTarget() instanceof UnsafeDeserializer and
sink.asExpr() = mc.getQualifier()
)
}
}
/**
* Safe deserializer creation to usage tracking config.
*/
abstract class SafeConstructorTrackingConfig extends TaintTracking2::Configuration {
bindingset[this]
SafeConstructorTrackingConfig() { any() }
}
/** BinaryFormatter */
private predicate isBinaryFormatterCall(MethodCall mc, Method m) {
m = mc.getTarget() and
(
not mc.getArgument(0).hasValue() and
(
m instanceof BinaryFormatterDeserializeMethod
or
m instanceof BinaryFormatterUnsafeDeserializeMethod
or
m instanceof BinaryFormatterUnsafeDeserializeMethodResponseMethod
)
)
}
abstract private class BinaryFormatterSink extends InstanceMethodSink { }
private class BinaryFormatterDeserializeMethodSink extends BinaryFormatterSink {
BinaryFormatterDeserializeMethodSink() {
exists(MethodCall mc, Method m |
isBinaryFormatterCall(mc, m) and
this.asExpr() = mc.getArgument(0)
)
}
}
/** SoapFormatter */
private predicate isSoapFormatterCall(MethodCall mc, Method m) {
m = mc.getTarget() and
m instanceof SoapFormatterDeserializeMethod and
not mc.getArgument(0).hasValue()
}
abstract private class SoapFormatterSink extends InstanceMethodSink { }
private class SoapFormatterDeserializeMethodSink extends SoapFormatterSink {
SoapFormatterDeserializeMethodSink() {
exists(MethodCall mc, Method m |
isSoapFormatterCall(mc, m) and
this.asExpr() = mc.getArgument(0)
)
}
}
/** ObjectStateFormatter */
private predicate isObjectStateFormatterCall(MethodCall mc, Method m) {
m = mc.getTarget() and
m instanceof ObjectStateFormatterDeserializeMethod and
not mc.getArgument(0).hasValue()
}
abstract private class ObjectStateFormatterSink extends InstanceMethodSink { }
private class ObjectStateFormatterDeserializeMethodSink extends ObjectStateFormatterSink {
ObjectStateFormatterDeserializeMethodSink() {
exists(MethodCall mc, Method m |
isObjectStateFormatterCall(mc, m) and
this.asExpr() = mc.getArgument(0)
)
}
}
/** NetDataContractSerializer */
private predicate isNetDataContractSerializerCall(MethodCall mc, Method m) {
m = mc.getTarget() and
(
(
m instanceof NetDataContractSerializerDeserializeMethod
or
m instanceof NetDataContractSerializerReadObjectMethod
) and
not mc.getArgument(0).hasValue()
)
}
abstract private class NetDataContractSerializerSink extends InstanceMethodSink { }
private class NetDataContractSerializerDeserializeMethodSink extends NetDataContractSerializerSink {
NetDataContractSerializerDeserializeMethodSink() {
exists(MethodCall mc, Method m |
isNetDataContractSerializerCall(mc, m) and
this.asExpr() = mc.getArgument(0)
)
}
}
/** DataContractJsonSerializer */
private predicate isDataContractJsonSerializerCall(MethodCall mc, Method m) {
m = mc.getTarget() and
m instanceof DataContractJsonSerializerReadObjectMethod and
not mc.getArgument(0).hasValue()
}
abstract private class DataContractJsonSerializerSink extends InstanceMethodSink { }
private class DataContractJsonSerializerDeserializeMethodSink extends DataContractJsonSerializerSink {
DataContractJsonSerializerDeserializeMethodSink() {
exists(MethodCall mc, Method m |
isDataContractJsonSerializerCall(mc, m) and
this.asExpr() = mc.getArgument(0)
)
}
}
private class DataContractJsonSafeConstructorTrackingConfiguration extends SafeConstructorTrackingConfig {
DataContractJsonSafeConstructorTrackingConfiguration() {
this = "DataContractJsonSafeConstructorTrackingConfiguration"
}
override predicate isSource(DataFlow::Node source) {
exists(ObjectCreation oc |
oc = source.asExpr() and
exists(Constructor c |
c = oc.getTarget() and
c.getDeclaringType() instanceof DataContractJsonSerializerClass and
c.getNumberOfParameters() > 0 and
oc.getArgument(0) instanceof TypeofExpr
)
)
}
override predicate isSink(DataFlow::Node sink) {
exists(MethodCall mc, Method m |
isDataContractJsonSerializerCall(mc, m) and
mc.getQualifier() = sink.asExpr()
)
}
}
/** JavaScriptSerializer */
private predicate isJavaScriptSerializerCall(MethodCall mc, Method m) {
m = mc.getTarget() and
(
(
m instanceof JavaScriptSerializerClassDeserializeMethod
or
m instanceof JavaScriptSerializerClassDeserializeObjectMethod
) and
not mc.getArgument(0).hasValue()
)
}
abstract private class JavaScriptSerializerSink extends InstanceMethodSink { }
private class JavaScriptSerializerDeserializeMethodSink extends JavaScriptSerializerSink {
JavaScriptSerializerDeserializeMethodSink() {
exists(MethodCall mc, Method m |
isJavaScriptSerializerCall(mc, m) and
this.asExpr() = mc.getArgument(0)
)
}
}
private class JavaScriptSerializerSafeConstructorTrackingConfiguration extends SafeConstructorTrackingConfig {
JavaScriptSerializerSafeConstructorTrackingConfiguration() {
this = "JavaScriptSerializerSafeConstructorTrackingConfiguration"
}
override predicate isSource(DataFlow::Node source) {
exists(ObjectCreation oc |
oc = source.asExpr() and
exists(Constructor c |
c = oc.getTarget() and
c.getDeclaringType() instanceof JavaScriptSerializerClass and
c.getNumberOfParameters() = 0
)
)
}
override predicate isSink(DataFlow::Node sink) {
exists(MethodCall mc, Method m |
isJavaScriptSerializerCall(mc, m) and
mc.getQualifier() = sink.asExpr()
)
}
}
/** XmlObjectSerializer */
private predicate isXmlObjectSerializerCall(MethodCall mc, Method m) {
m = mc.getTarget() and
m instanceof XmlObjectSerializerReadObjectMethod and
not mc.getArgument(0).hasValue() and
not mc.targetIsLocalInstance()
}
abstract private class XmlObjectSerializerSink extends InstanceMethodSink { }
private class XmlObjectSerializerDeserializeMethodSink extends XmlObjectSerializerSink {
XmlObjectSerializerDeserializeMethodSink() {
exists(MethodCall mc, Method m |
isXmlObjectSerializerCall(mc, m) and
this.asExpr() = mc.getArgument(0)
)
}
}
private class XmlObjectSerializerDerivedConstructorTrackingConfiguration extends SafeConstructorTrackingConfig {
XmlObjectSerializerDerivedConstructorTrackingConfiguration() {
this = "XmlObjectSerializerDerivedConstructorTrackingConfiguration"
}
override predicate isSource(DataFlow::Node source) {
exists(ObjectCreation oc |
oc = source.asExpr() and
exists(ValueOrRefType declaringType |
declaringType = oc.getTarget().getDeclaringType() and
declaringType.getABaseType+() instanceof XmlObjectSerializerClass and
not (
declaringType instanceof DataContractSerializerClass or
declaringType instanceof NetDataContractSerializerClass
)
)
)
}
override predicate isSink(DataFlow::Node sink) {
exists(MethodCall mc, Method m |
isXmlObjectSerializerCall(mc, m) and
mc.getQualifier() = sink.asExpr()
)
}
}
/** XmlSerializer */
private predicate isXmlSerializerCall(MethodCall mc, Method m) {
m = mc.getTarget() and
m instanceof XmlSerializerDeserializeMethod and
not mc.getArgument(0).hasValue()
}
abstract private class XmlSerializerSink extends InstanceMethodSink { }
private class XmlSerializerDeserializeMethodSink extends XmlSerializerSink {
XmlSerializerDeserializeMethodSink() {
exists(MethodCall mc, Method m |
isXmlSerializerCall(mc, m) and
this.asExpr() = mc.getArgument(0)
)
}
}
private class XmlSerializerSafeConstructorTrackingConfiguration extends SafeConstructorTrackingConfig {
XmlSerializerSafeConstructorTrackingConfiguration() {
this = "XmlSerializerSafeConstructorTrackingConfiguration"
}
override predicate isSource(DataFlow::Node source) {
exists(ObjectCreation oc |
oc = source.asExpr() and
exists(Constructor c |
c = oc.getTarget() and
c.getDeclaringType() instanceof XmlSerializerClass and
c.getNumberOfParameters() > 0 and
oc.getArgument(0) instanceof TypeofExpr
)
)
}
override predicate isSink(DataFlow::Node sink) {
exists(MethodCall mc, Method m |
isXmlSerializerCall(mc, m) and
mc.getQualifier() = sink.asExpr()
)
}
}
/** DataContractSerializer */
private predicate isDataContractSerializerCall(MethodCall mc, Method m) {
m = mc.getTarget() and
(
m instanceof DataContractSerializerReadObjectMethod
or
m instanceof XmlObjectSerializerReadObjectMethod
) and
not mc.getArgument(0).hasValue()
}
abstract private class DataContractSerializerSink extends InstanceMethodSink { }
private class DataContractSerializerDeserializeMethodSink extends DataContractSerializerSink {
DataContractSerializerDeserializeMethodSink() {
exists(MethodCall mc, Method m |
isDataContractSerializerCall(mc, m) and
this.asExpr() = mc.getArgument(0)
)
}
}
private class DataContractSerializerSafeConstructorTrackingConfiguration extends SafeConstructorTrackingConfig {
DataContractSerializerSafeConstructorTrackingConfiguration() {
this = "DataContractSerializerSafeConstructorTrackingConfiguration"
}
override predicate isSource(DataFlow::Node source) {
exists(ObjectCreation oc |
oc = source.asExpr() and
exists(Constructor c |
c = oc.getTarget() and
c.getDeclaringType() instanceof DataContractSerializerClass and
c.getNumberOfParameters() > 0 and
oc.getArgument(0) instanceof TypeofExpr
)
)
}
override predicate isSink(DataFlow::Node sink) {
exists(MethodCall mc, Method m |
isDataContractSerializerCall(mc, m) and
mc.getQualifier() = sink.asExpr()
)
}
}
/** XmlMessageFormatter */
private predicate isXmlMessageFormatterCall(MethodCall mc, Method m) {
m = mc.getTarget() and
m instanceof XmlMessageFormatterReadMethod and
not mc.getArgument(0).hasValue()
}
abstract private class XmlMessageFormatterSink extends InstanceMethodSink { }
private class XmlMessageFormatterDeserializeMethodSink extends XmlMessageFormatterSink {
XmlMessageFormatterDeserializeMethodSink() {
exists(MethodCall mc, Method m |
isXmlMessageFormatterCall(mc, m) and
this.asExpr() = mc.getArgument(0)
)
}
}
private class XmlMessageFormatterSafeConstructorTrackingConfiguration extends SafeConstructorTrackingConfig {
XmlMessageFormatterSafeConstructorTrackingConfiguration() {
this = "XmlMessageFormatterSafeConstructorTrackingConfiguration"
}
override predicate isSource(DataFlow::Node source) {
exists(ObjectCreation oc |
oc = source.asExpr() and
exists(Constructor c |
c = oc.getTarget() and
c.getDeclaringType() instanceof XmlMessageFormatterClass and
c.getNumberOfParameters() > 0 and
oc.getArgument(0) instanceof TypeofExpr
)
)
}
override predicate isSink(DataFlow::Node sink) {
exists(MethodCall mc, Method m |
isXmlMessageFormatterCall(mc, m) and
mc.getQualifier() = sink.asExpr()
)
}
}
/** LosFormatter */
private predicate isLosFormatterCall(MethodCall mc, Method m) {
m = mc.getTarget() and
m instanceof LosFormatterDeserializeMethod and
not mc.getArgument(0).hasValue()
}
abstract private class LosFormatterSink extends InstanceMethodSink { }
private class LosFormatterDeserializeMethodSink extends LosFormatterSink {
LosFormatterDeserializeMethodSink() {
exists(MethodCall mc, Method m |
isLosFormatterCall(mc, m) and
this.asExpr() = mc.getArgument(0)
)
}
}
/** fastJSON */
private predicate isFastJsonCall(MethodCall mc, Method m) {
m = mc.getTarget() and
m instanceof FastJsonClassToObjectMethod and
not mc.getArgument(0).hasValue()
}
abstract private class FastJsonSink extends ConstructorOrStaticMethodSink { }
private class FastJsonDeserializeMethodSink extends FastJsonSink {
FastJsonDeserializeMethodSink() {
exists(MethodCall mc, Method m |
isFastJsonCall(mc, m) and
this.asExpr() = mc.getArgument(0)
)
}
}
/** Activity */
private predicate isActivityCall(MethodCall mc, Method m) {
m = mc.getTarget() and
m instanceof ActivityLoadMethod and
not mc.getArgument(0).hasValue()
}
abstract private class ActivitySink extends InstanceMethodSink { }
private class ActivityDeserializeMethodSink extends ActivitySink {
ActivityDeserializeMethodSink() {
exists(MethodCall mc, Method m |
isActivityCall(mc, m) and
this.asExpr() = mc.getArgument(0)
)
}
}
/** ResourceReader */
private predicate isResourceReaderCall(Call mc, Constructor m) {
m = mc.getTarget() and
m instanceof ResourceReaderConstructor and
not mc.getArgument(0).hasValue()
}
abstract private class ResourceReaderSink extends ConstructorOrStaticMethodSink { }
private class ResourceReaderDeserializeMethodSink extends ResourceReaderSink {
ResourceReaderDeserializeMethodSink() {
exists(Call mc, Constructor m |
isResourceReaderCall(mc, m) and
this.asExpr() = mc.getArgument(0)
)
}
}
/** BinaryMessageFormatter */
private predicate isBinaryMessageFormatterCall(MethodCall mc, Method m) {
m = mc.getTarget() and
m instanceof BinaryMessageFormatterReadMethod and
not mc.getArgument(0).hasValue()
}
abstract private class BinaryMessageFormatterSink extends InstanceMethodSink { }
private class BinaryMessageFormatterDeserializeMethodSink extends BinaryMessageFormatterSink {
BinaryMessageFormatterDeserializeMethodSink() {
exists(MethodCall mc, Method m |
isBinaryMessageFormatterCall(mc, m) and
this.asExpr() = mc.getArgument(0)
)
}
}
/** XamlReader */
private predicate isXamlReaderCall(MethodCall mc, Method m) {
m = mc.getTarget() and
(
m instanceof XamlReaderParseMethod
or
m instanceof XamlReaderLoadMethod
or
m instanceof XamlReaderLoadAsyncMethod
) and
not mc.getArgument(0).hasValue()
}
abstract private class XamlReaderSink extends ConstructorOrStaticMethodSink { }
private class XamlReaderDeserializeMethodSink extends XamlReaderSink {
XamlReaderDeserializeMethodSink() {
exists(MethodCall mc, Method m |
isXamlReaderCall(mc, m) and
this.asExpr() = mc.getArgument(0)
)
}
}
/** ProxyObject */
private predicate isProxyObjectCall(MethodCall mc, Method m) {
m = mc.getTarget() and
(
m instanceof ProxyObjectDecodeValueMethod
or
m instanceof ProxyObjectDecodeSerializedObjectMethod
) and
not mc.getArgument(0).hasValue()
}
abstract private class ProxyObjectSink extends InstanceMethodSink { }
private class ProxyObjectDeserializeMethodSink extends ProxyObjectSink {
ProxyObjectDeserializeMethodSink() {
exists(MethodCall mc, Method m |
isProxyObjectCall(mc, m) and
this.asExpr() = mc.getArgument(0)
)
}
}
/** SweetJayson */
private predicate isSweetJaysonCall(MethodCall mc, Method m) {
m = mc.getTarget() and
m instanceof JaysonConverterToObjectMethod and
not mc.getArgument(0).hasValue()
}
abstract private class SweetJaysonSink extends ConstructorOrStaticMethodSink { }
private class SweetJaysonDeserializeMethodSink extends SweetJaysonSink {
SweetJaysonDeserializeMethodSink() {
exists(MethodCall mc, Method m |
isSweetJaysonCall(mc, m) and
this.asExpr() = mc.getArgument(0)
)
}
}
/** ServiceStack.Text.JsonSerializer */
abstract private class ServiceStackTextJsonSerializerSink extends ConstructorOrStaticMethodSink { }
private class ServiceStackTextJsonSerializerDeserializeMethodSink extends ServiceStackTextJsonSerializerSink {
ServiceStackTextJsonSerializerDeserializeMethodSink() {
exists(MethodCall mc, Method m |
m = mc.getTarget() and
(
m instanceof ServiceStackTextJsonSerializerDeserializeFromStringMethod
or
m instanceof ServiceStackTextJsonSerializerDeserializeFromReaderMethod
or
m instanceof ServiceStackTextJsonSerializerDeserializeFromStreamMethod
) and
exists(Expr arg |
arg = mc.getAnArgument() and
not arg.hasValue() and
not arg instanceof TypeofExpr and
this.asExpr() = arg
)
)
}
}
/** ServiceStack.Text.TypeSerializer */
abstract private class ServiceStackTextTypeSerializerSink extends ConstructorOrStaticMethodSink { }
private class ServiceStackTextTypeSerializerDeserializeMethodSink extends ServiceStackTextTypeSerializerSink {
ServiceStackTextTypeSerializerDeserializeMethodSink() {
exists(MethodCall mc, Method m |
m = mc.getTarget() and
(
m instanceof ServiceStackTextTypeSerializerDeserializeFromStringMethod
or
m instanceof ServiceStackTextTypeSerializerDeserializeFromReaderMethod
or
m instanceof ServiceStackTextTypeSerializerDeserializeFromStreamMethod
) and
exists(Expr arg |
arg = mc.getAnArgument() and
not arg.hasValue() and
not arg instanceof TypeofExpr and
this.asExpr() = arg
)
)
}
}
/** ServiceStack.Text.CsvSerializer */
abstract private class ServiceStackTextCsvSerializerSink extends ConstructorOrStaticMethodSink { }
private class ServiceStackTextCsvSerializerDeserializeMethodSink extends ServiceStackTextCsvSerializerSink {
ServiceStackTextCsvSerializerDeserializeMethodSink() {
exists(MethodCall mc, Method m |
m = mc.getTarget() and
(
m instanceof ServiceStackTextCsvSerializerDeserializeFromStringMethod
or
m instanceof ServiceStackTextCsvSerializerDeserializeFromReaderMethod
or
m instanceof ServiceStackTextCsvSerializerDeserializeFromStreamMethod
) and
exists(Expr arg |
arg = mc.getAnArgument() and
not arg.hasValue() and
not arg instanceof TypeofExpr and
this.asExpr() = arg
)
)
}
}
/** ServiceStack.Text.XmlSerializer */
abstract private class ServiceStackTextXmlSerializerSink extends ConstructorOrStaticMethodSink { }
private class ServiceStackTextXmlSerializerDeserializeMethodSink extends ServiceStackTextXmlSerializerSink {
ServiceStackTextXmlSerializerDeserializeMethodSink() {
exists(MethodCall mc, Method m |
m = mc.getTarget() and
(
m instanceof ServiceStackTextXmlSerializerDeserializeFromStringMethod
or
m instanceof ServiceStackTextXmlSerializerDeserializeFromReaderMethod
or
m instanceof ServiceStackTextXmlSerializerDeserializeFromStreamMethod
) and
exists(Expr arg |
arg = mc.getAnArgument() and
not arg.hasValue() and
not arg instanceof TypeofExpr and
this.asExpr() = arg
)
)
}
}
/** FsPickler */
private predicate isWeakTypeFsPicklerCall(MethodCall mc, Method m) {
m = mc.getTarget() and
(
m instanceof FsPicklerSerializerClassUnPickleUntypedMethod or
m instanceof FsPicklerSerializerClassDeserializeUntypedMethod or
m instanceof FsPicklerSerializerClassDeserializeSequenceUntypedMethod
) and
not mc.getArgument(0).hasValue()
}
abstract private class FsPicklerWeakTypeSink extends ConstructorOrStaticMethodSink { }
private class FsPicklerDeserializeWeakTypeMethodSink extends FsPicklerWeakTypeSink {
FsPicklerDeserializeWeakTypeMethodSink() {
exists(MethodCall mc, Method m |
isWeakTypeFsPicklerCall(mc, m) and
this.asExpr() = mc.getArgument(0)
)
}
}
private predicate isStrongTypeFsPicklerCall(MethodCall mc, Method m) {
m = mc.getTarget() and
(
m instanceof FsPicklerSerializerClassDeserializeMethod or
m instanceof FsPicklerSerializerClassDeserializeSequenceMethod or
m instanceof FsPicklerSerializerClasDeserializeSiftedMethod or
m instanceof FsPicklerSerializerClassUnPickleMethod or
m instanceof FsPicklerSerializerClassUnPickleSiftedMethod or
m instanceof CsPicklerSerializerClassDeserializeMethod or
m instanceof CsPicklerSerializerClassUnPickleMethod or
m instanceof CsPicklerSerializerClassUnPickleOfStringMethod
) and
not mc.getArgument(0).hasValue()
}
abstract private class FsPicklerStrongTypeSink extends InstanceMethodSink { }
private class FsPicklerDeserializeStrongTypeMethodSink extends FsPicklerStrongTypeSink {
FsPicklerDeserializeStrongTypeMethodSink() {
exists(MethodCall mc, Method m |
isStrongTypeFsPicklerCall(mc, m) and
this.asExpr() = mc.getArgument(0)
)
}
}
/** SharpSerializer */
private class SharpSerializerDeserializeMethodSink extends InstanceMethodSink {
SharpSerializerDeserializeMethodSink() {
exists(MethodCall mc, Method m |
m = mc.getTarget() and
(
not mc.getArgument(0).hasValue() and
m instanceof SharpSerializerClassDeserializeMethod
) and
this.asExpr() = mc.getArgument(0)
)
}
}
/** YamlDotNet */
private class YamlDotNetDeserializerDeserializeMethodSink extends ConstructorOrStaticMethodSink {
YamlDotNetDeserializerDeserializeMethodSink() {
exists(MethodCall mc, Method m |
m = mc.getTarget() and
(
not mc.getArgument(0).hasValue() and
m instanceof YamlDotNetDeserializerClasseserializeMethod
) and
this.asExpr() = mc.getArgument(0)
)
}
}
/** Newtonsoft.Json.JsonConvert */
private class NewtonsoftJsonConvertDeserializeObjectMethodSink extends ConstructorOrStaticMethodSink {
NewtonsoftJsonConvertDeserializeObjectMethodSink() {
exists(MethodCall mc, Method m |
m = mc.getTarget() and
(
not mc.getArgument(0).hasValue() and
m instanceof NewtonsoftJsonConvertClassDeserializeObjectMethod
) and
this.asExpr() = mc.getArgument(0)
)
}
}

View File

@@ -4,51 +4,72 @@
*/
import csharp
import semmle.code.csharp.frameworks.JsonNET::JsonNET
/** An unsafe deserializer. */
abstract class UnsafeDeserializer extends Callable { }
/** An unsafe deserializer method in the `System.*` namespace. */
class SystemDeserializer extends UnsafeDeserializer {
SystemDeserializer() {
this.hasQualifiedName("System.Runtime.Serialization.Formatters.Binary.BinaryFormatter",
"Deserialize")
/** A deserializer exploitable only if user controls the expected object type. */
class StrongTypeDeserializer extends Class {
StrongTypeDeserializer() {
this instanceof XmlSerializerClass
or
this.hasQualifiedName("System.Runtime.Serialization.Formatters.Binary.BinaryFormatter",
"UnsafeDeserialize")
this instanceof DataContractJsonSerializerClass
or
this.hasQualifiedName("System.Runtime.Serialization.Formatters.Binary.BinaryFormatter",
"UnsafeDeserializeMethodResponse")
this instanceof DataContractSerializerClass
or
this.hasQualifiedName("System.Runtime.Deserialization.Formatters.Soap.SoapFormatter",
"Deserialize")
this instanceof XmlMessageFormatterClass
or
this.hasQualifiedName("System.Web.UI.ObjectStateFormatter", "Deserialize")
this instanceof FsPicklerSerializerClass
or
this.hasQualifiedName("System.Runtime.Serialization.NetDataContractSerializer", "Deserialize")
this instanceof CsPicklerSerializerClass
or
this.hasQualifiedName("System.Runtime.Serialization.NetDataContractSerializer", "ReadObject")
or
this.hasQualifiedName("System.Web.UI.LosFormatter", "Deserialize")
or
this.hasQualifiedName("System.Workflow.ComponentModel.Activity", "Load")
or
this.hasQualifiedName("System.Resources.ResourceReader", "ResourceReader")
or
this.hasQualifiedName("System.Messaging", "BinaryMessageFormatter")
or
this.hasQualifiedName("System.Windows.Markup.XamlReader", "Parse")
or
this.hasQualifiedName("System.Windows.Markup.XamlReader", "Load")
or
this.hasQualifiedName("System.Windows.Markup.XamlReader", "LoadAsync")
this instanceof CsPicklerTextSerializerClass
}
}
/** An unsafe deserializer method in the `Microsoft.*` namespace. */
class MicrosoftDeserializer extends UnsafeDeserializer {
MicrosoftDeserializer() {
this.hasQualifiedName("Microsoft.Web.Design.Remote.ProxyObject", "DecodeValue")
/** A deserializer that doesn't make strong expected type check. */
class WeakTypeDeserializer extends Class {
WeakTypeDeserializer() {
this instanceof BinaryFormatterClass
or
this instanceof SoapFormatterClass
or
this instanceof ObjectStateFormatterClass
or
this instanceof NetDataContractSerializerClass
or
this instanceof JavaScriptSerializerClass
or
this instanceof LosFormatterClass
or
this instanceof BinaryMessageFormatterClass
or
this instanceof FastJsonClass
or
this instanceof ActivityClass
or
this instanceof XamlReaderClass
or
this instanceof ProxyObjectClass
or
this instanceof ResourceReaderClass
or
this instanceof JaysonConverterClass
or
this instanceof ServiceStackTextJsonSerializerClass
or
this instanceof ServiceStackTextTypeSerializerClass
or
this instanceof ServiceStackTextCsvSerializerClass
or
this instanceof ServiceStackTextXmlSerializerClass
or
this instanceof SharpSerializerClass
or
this instanceof YamlDotNetDeserializerClass
or
this instanceof JsonConvertClass
}
}
@@ -56,7 +77,7 @@ class MicrosoftDeserializer extends UnsafeDeserializer {
* An unsafe deserializer method that calls any unsafe deserializer on any of
* the parameters.
*/
class WrapperDeserializer extends UnsafeDeserializer {
private class WrapperDeserializer extends UnsafeDeserializer {
WrapperDeserializer() {
exists(Call call |
call.getEnclosingCallable() = this and
@@ -65,3 +86,586 @@ class WrapperDeserializer extends UnsafeDeserializer {
)
}
}
/** BinaryFormatter */
private class BinaryFormatterClass extends Class {
BinaryFormatterClass() {
this.hasQualifiedName("System.Runtime.Serialization.Formatters.Binary.BinaryFormatter")
}
}
/** `System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize` method */
class BinaryFormatterDeserializeMethod extends Method, UnsafeDeserializer {
BinaryFormatterDeserializeMethod() {
this.getDeclaringType() instanceof BinaryFormatterClass and
this.hasName("Deserialize")
}
}
/** `System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.UnsafeDeserialize` method */
class BinaryFormatterUnsafeDeserializeMethod extends Method, UnsafeDeserializer {
BinaryFormatterUnsafeDeserializeMethod() {
this.getDeclaringType() instanceof BinaryFormatterClass and
this.hasName("UnsafeDeserialize")
}
}
/** `System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.UnsafeDeserializeMethodResponse` method */
class BinaryFormatterUnsafeDeserializeMethodResponseMethod extends Method, UnsafeDeserializer {
BinaryFormatterUnsafeDeserializeMethodResponseMethod() {
this.getDeclaringType() instanceof BinaryFormatterClass and
this.hasName("UnsafeDeserializeMethodResponse")
}
}
/** SoapFormatter */
private class SoapFormatterClass extends Class {
SoapFormatterClass() {
this.hasQualifiedName("System.Runtime.Serialization.Formatters.Soap.SoapFormatter")
}
}
/** `System.Runtime.Serialization.Formatters.Soap.SoapFormatter.Deserialize` method */
class SoapFormatterDeserializeMethod extends Method, UnsafeDeserializer {
SoapFormatterDeserializeMethod() {
this.getDeclaringType() instanceof SoapFormatterClass and
this.hasName("Deserialize")
}
}
/** ObjectStateFormatter */
private class ObjectStateFormatterClass extends Class {
ObjectStateFormatterClass() { this.hasQualifiedName("System.Web.UI.ObjectStateFormatter") }
}
/** `System.Web.UI.ObjectStateFormatter.Deserialize` method */
class ObjectStateFormatterDeserializeMethod extends Method, UnsafeDeserializer {
ObjectStateFormatterDeserializeMethod() {
this.getDeclaringType() instanceof ObjectStateFormatterClass and
this.hasName("Deserialize")
}
}
/** NetDataContractSerializer */
class NetDataContractSerializerClass extends Class {
NetDataContractSerializerClass() {
this.hasQualifiedName("System.Runtime.Serialization.NetDataContractSerializer")
}
}
/** `System.Runtime.Serialization.NetDataContractSerializer.Deserialize` method */
class NetDataContractSerializerDeserializeMethod extends Method, UnsafeDeserializer {
NetDataContractSerializerDeserializeMethod() {
this.getDeclaringType() instanceof NetDataContractSerializerClass and
this.hasName("Deserialize")
}
}
/** `System.Runtime.Serialization.NetDataContractSerializer.ReadObject` method */
class NetDataContractSerializerReadObjectMethod extends Method, UnsafeDeserializer {
NetDataContractSerializerReadObjectMethod() {
this.getDeclaringType() instanceof NetDataContractSerializerClass and
this.hasName("ReadObject")
}
}
/** DataContractJsonSerializer */
class DataContractJsonSerializerClass extends Class {
DataContractJsonSerializerClass() {
this.hasQualifiedName("System.Runtime.Serialization.Json.DataContractJsonSerializer")
}
}
/** `System.Runtime.Serialization.Json.DataContractJsonSerializer.ReadObject` method */
class DataContractJsonSerializerReadObjectMethod extends Method, UnsafeDeserializer {
DataContractJsonSerializerReadObjectMethod() {
this.getDeclaringType() instanceof DataContractJsonSerializerClass and
this.hasName("ReadObject")
}
}
/** JavaScriptSerializer */
class JavaScriptSerializerClass extends Class {
JavaScriptSerializerClass() {
this.hasQualifiedName("System.Web.Script.Serialization.JavaScriptSerializer")
}
}
/** `System.Web.Script.Serialization.JavaScriptSerializer.Deserialize` method */
class JavaScriptSerializerClassDeserializeMethod extends Method, UnsafeDeserializer {
JavaScriptSerializerClassDeserializeMethod() {
this.getDeclaringType() instanceof JavaScriptSerializerClass and
this.hasName("Deserialize")
}
}
/** `System.Web.Script.Serialization.JavaScriptSerializer.DeserializeObject` method */
class JavaScriptSerializerClassDeserializeObjectMethod extends Method, UnsafeDeserializer {
JavaScriptSerializerClassDeserializeObjectMethod() {
this.getDeclaringType() instanceof JavaScriptSerializerClass and
this.hasName("DeserializeObject")
}
}
/** XmlObjectSerializer */
class XmlObjectSerializerClass extends Class {
XmlObjectSerializerClass() {
this.hasQualifiedName("System.Runtime.Serialization.XmlObjectSerializer")
}
}
/** `System.Runtime.Serialization.XmlObjectSerializer.ReadObject` method */
class XmlObjectSerializerReadObjectMethod extends Method, UnsafeDeserializer {
XmlObjectSerializerReadObjectMethod() {
this.getDeclaringType() instanceof XmlObjectSerializerClass and
this.hasName("ReadObject")
}
}
/** XmlSerializer */
class XmlSerializerClass extends Class {
XmlSerializerClass() { this.hasQualifiedName("System.Xml.Serialization.XmlSerializer") }
}
/** `System.Xml.Serialization.XmlSerializer.Deserialize` method */
class XmlSerializerDeserializeMethod extends Method, UnsafeDeserializer {
XmlSerializerDeserializeMethod() {
this.getDeclaringType() instanceof XmlSerializerClass and
this.hasName("Deserialize")
}
}
/** DataContractSerializer */
class DataContractSerializerClass extends Class {
DataContractSerializerClass() {
this.hasQualifiedName("System.Runtime.Serialization.DataContractSerializer")
}
}
/** `System.Runtime.Serialization.DataContractSerializer.ReadObject` method */
class DataContractSerializerReadObjectMethod extends Method, UnsafeDeserializer {
DataContractSerializerReadObjectMethod() {
this.getDeclaringType() instanceof DataContractSerializerClass and
this.hasName("ReadObject")
}
}
/** XmlMessageFormatter */
class XmlMessageFormatterClass extends Class {
XmlMessageFormatterClass() { this.hasQualifiedName("System.Messaging.XmlMessageFormatter") }
}
/** `System.Messaging.XmlMessageFormatter.Read` method */
class XmlMessageFormatterReadMethod extends Method, UnsafeDeserializer {
XmlMessageFormatterReadMethod() {
this.getDeclaringType() instanceof XmlMessageFormatterClass and
this.hasName("Read")
}
}
/** LosFormatter */
private class LosFormatterClass extends Class {
LosFormatterClass() { this.hasQualifiedName("System.Web.UI.LosFormatter") }
}
/** `System.Web.UI.LosFormatter.Deserialize` method */
class LosFormatterDeserializeMethod extends Method, UnsafeDeserializer {
LosFormatterDeserializeMethod() {
this.getDeclaringType() instanceof LosFormatterClass and
this.hasName("Deserialize")
}
}
/** fastJSON */
private class FastJsonClass extends Class {
FastJsonClass() { this.hasQualifiedName("fastJSON.JSON") }
}
/** `fastJSON.JSON.ToObject` method */
class FastJsonClassToObjectMethod extends Method, UnsafeDeserializer {
FastJsonClassToObjectMethod() {
this.getDeclaringType() instanceof FastJsonClass and
this.hasName("ToObject") and
this.isStatic()
}
}
/** Activity */
private class ActivityClass extends Class {
ActivityClass() { this.hasQualifiedName("System.Workflow.ComponentModel.Activity") }
}
/** `System.Workflow.ComponentModel.Activity.Load` method */
class ActivityLoadMethod extends Method, UnsafeDeserializer {
ActivityLoadMethod() {
this.getDeclaringType() instanceof ActivityClass and
this.hasName("Load")
}
}
/** ResourceReader */
private class ResourceReaderClass extends Class {
ResourceReaderClass() { this.hasQualifiedName("System.Resources.ResourceReader") }
}
/** `System.Resources.ResourceReader` constructor */
class ResourceReaderConstructor extends Constructor, UnsafeDeserializer {
ResourceReaderConstructor() {
this.getDeclaringType() instanceof ResourceReaderClass and
this.hasName("ResourceReader")
}
}
/** BinaryMessageFormatter */
private class BinaryMessageFormatterClass extends Class {
BinaryMessageFormatterClass() { this.hasQualifiedName("System.Messaging.BinaryMessageFormatter") }
}
/** `System.Messaging.BinaryMessageFormatter.Read` method */
class BinaryMessageFormatterReadMethod extends Method, UnsafeDeserializer {
BinaryMessageFormatterReadMethod() {
this.getDeclaringType() instanceof BinaryMessageFormatterClass and
this.hasName("Read")
}
}
/** XamlReader */
private class XamlReaderClass extends Class {
XamlReaderClass() { this.hasQualifiedName("System.Windows.Markup.XamlReader") }
}
/** `System.Windows.Markup.XamlReader.Parse` method */
class XamlReaderParseMethod extends Method, UnsafeDeserializer {
XamlReaderParseMethod() {
this.getDeclaringType() instanceof XamlReaderClass and
this.hasName("Parse") and
this.isStatic()
}
}
/** `System.Windows.Markup.XamlReader.Load` method */
class XamlReaderLoadMethod extends Method, UnsafeDeserializer {
XamlReaderLoadMethod() {
this.getDeclaringType() instanceof XamlReaderClass and
this.hasName("Load") and
this.isStatic()
}
}
/** `System.Windows.Markup.XamlReader.LoadAsync` method */
class XamlReaderLoadAsyncMethod extends Method, UnsafeDeserializer {
XamlReaderLoadAsyncMethod() {
this.getDeclaringType() instanceof XamlReaderClass and
this.hasName("LoadAsync")
}
}
/** ProxyObject */
private class ProxyObjectClass extends Class {
ProxyObjectClass() { this.hasQualifiedName("Microsoft.Web.Design.Remote.ProxyObject") }
}
/** `Microsoft.Web.Design.Remote.ProxyObject.DecodeValue` method */
class ProxyObjectDecodeValueMethod extends Method, UnsafeDeserializer {
ProxyObjectDecodeValueMethod() {
this.getDeclaringType() instanceof ProxyObjectClass and
this.hasName("DecodeValue")
}
}
/** `Microsoft.Web.Design.Remote.ProxyObject.DecodeSerializedObject` method */
class ProxyObjectDecodeSerializedObjectMethod extends Method, UnsafeDeserializer {
ProxyObjectDecodeSerializedObjectMethod() {
this.getDeclaringType() instanceof ProxyObjectClass and
this.hasName("DecodeSerializedObject")
}
}
/** SweetJayson */
private class JaysonConverterClass extends Class {
JaysonConverterClass() { this.hasQualifiedName("Sweet.Jayson.JaysonConverter") }
}
/** `Sweet.Jayson.JaysonConverter.ToObject` method */
class JaysonConverterToObjectMethod extends Method, UnsafeDeserializer {
JaysonConverterToObjectMethod() {
this.getDeclaringType() instanceof JaysonConverterClass and
this.hasName("ToObject") and
this.isStatic()
}
}
/** ServiceStack.Text.JsonSerializer */
private class ServiceStackTextJsonSerializerClass extends Class {
ServiceStackTextJsonSerializerClass() {
this.hasQualifiedName("ServiceStack.Text.JsonSerializer")
}
}
/** `ServiceStack.Text.JsonSerializer.DeserializeFromString` method */
class ServiceStackTextJsonSerializerDeserializeFromStringMethod extends Method, UnsafeDeserializer {
ServiceStackTextJsonSerializerDeserializeFromStringMethod() {
this.getDeclaringType() instanceof ServiceStackTextJsonSerializerClass and
this.hasName("DeserializeFromString") and
this.isStatic()
}
}
/** `ServiceStack.Text.JsonSerializer.DeserializeFromReader` method */
class ServiceStackTextJsonSerializerDeserializeFromReaderMethod extends Method, UnsafeDeserializer {
ServiceStackTextJsonSerializerDeserializeFromReaderMethod() {
this.getDeclaringType() instanceof ServiceStackTextJsonSerializerClass and
this.hasName("DeserializeFromReader") and
this.isStatic()
}
}
/** `ServiceStack.Text.JsonSerializer.DeserializeFromStream` method */
class ServiceStackTextJsonSerializerDeserializeFromStreamMethod extends Method, UnsafeDeserializer {
ServiceStackTextJsonSerializerDeserializeFromStreamMethod() {
this.getDeclaringType() instanceof ServiceStackTextJsonSerializerClass and
this.hasName("DeserializeFromStream") and
this.isStatic()
}
}
/** ServiceStack.Text.TypeSerializer */
private class ServiceStackTextTypeSerializerClass extends Class {
ServiceStackTextTypeSerializerClass() {
this.hasQualifiedName("ServiceStack.Text.TypeSerializer")
}
}
/** `ServiceStack.Text.TypeSerializer.DeserializeFromString` method */
class ServiceStackTextTypeSerializerDeserializeFromStringMethod extends Method, UnsafeDeserializer {
ServiceStackTextTypeSerializerDeserializeFromStringMethod() {
this.getDeclaringType() instanceof ServiceStackTextTypeSerializerClass and
this.hasName("DeserializeFromString") and
this.isStatic()
}
}
/** `ServiceStack.Text.TypeSerializer.DeserializeFromReader` method */
class ServiceStackTextTypeSerializerDeserializeFromReaderMethod extends Method, UnsafeDeserializer {
ServiceStackTextTypeSerializerDeserializeFromReaderMethod() {
this.getDeclaringType() instanceof ServiceStackTextTypeSerializerClass and
this.hasName("DeserializeFromReader") and
this.isStatic()
}
}
/** `ServiceStack.Text.TypeSerializer.DeserializeFromStream` method */
class ServiceStackTextTypeSerializerDeserializeFromStreamMethod extends Method, UnsafeDeserializer {
ServiceStackTextTypeSerializerDeserializeFromStreamMethod() {
this.getDeclaringType() instanceof ServiceStackTextTypeSerializerClass and
this.hasName("DeserializeFromStream") and
this.isStatic()
}
}
/** ServiceStack.Text.CsvSerializer */
private class ServiceStackTextCsvSerializerClass extends Class {
ServiceStackTextCsvSerializerClass() { this.hasQualifiedName("ServiceStack.Text.CsvSerializer") }
}
/** `ServiceStack.Text.CsvSerializer.DeserializeFromString` method */
class ServiceStackTextCsvSerializerDeserializeFromStringMethod extends Method, UnsafeDeserializer {
ServiceStackTextCsvSerializerDeserializeFromStringMethod() {
this.getDeclaringType() instanceof ServiceStackTextCsvSerializerClass and
this.hasName("DeserializeFromString") and
this.isStatic()
}
}
/** `ServiceStack.Text.TypeSeriCsvSerializeralizer.DeserializeFromReader` method */
class ServiceStackTextCsvSerializerDeserializeFromReaderMethod extends Method, UnsafeDeserializer {
ServiceStackTextCsvSerializerDeserializeFromReaderMethod() {
this.getDeclaringType() instanceof ServiceStackTextCsvSerializerClass and
this.hasName("DeserializeFromReader") and
this.isStatic()
}
}
/** `ServiceStack.Text.CsvSerializer.DeserializeFromStream` method */
class ServiceStackTextCsvSerializerDeserializeFromStreamMethod extends Method, UnsafeDeserializer {
ServiceStackTextCsvSerializerDeserializeFromStreamMethod() {
this.getDeclaringType() instanceof ServiceStackTextCsvSerializerClass and
this.hasName("DeserializeFromStream") and
this.isStatic()
}
}
/** ServiceStack.Text.XmlSerializer */
private class ServiceStackTextXmlSerializerClass extends Class {
ServiceStackTextXmlSerializerClass() { this.hasQualifiedName("ServiceStack.Text.XmlSerializer") }
}
/** `ServiceStack.Text.XmlSerializer.DeserializeFromString` method */
class ServiceStackTextXmlSerializerDeserializeFromStringMethod extends Method, UnsafeDeserializer {
ServiceStackTextXmlSerializerDeserializeFromStringMethod() {
this.getDeclaringType() instanceof ServiceStackTextXmlSerializerClass and
this.hasName("DeserializeFromString") and
this.isStatic()
}
}
/** `ServiceStack.Text.XmlSerializer.DeserializeFromReader` method */
class ServiceStackTextXmlSerializerDeserializeFromReaderMethod extends Method, UnsafeDeserializer {
ServiceStackTextXmlSerializerDeserializeFromReaderMethod() {
this.getDeclaringType() instanceof ServiceStackTextXmlSerializerClass and
this.hasName("DeserializeFromReader") and
this.isStatic()
}
}
/** `ServiceStack.Text.XmlSerializer.DeserializeFromStream` method */
class ServiceStackTextXmlSerializerDeserializeFromStreamMethod extends Method, UnsafeDeserializer {
ServiceStackTextXmlSerializerDeserializeFromStreamMethod() {
this.getDeclaringType() instanceof ServiceStackTextXmlSerializerClass and
this.hasName("DeserializeFromStream") and
this.isStatic()
}
}
/** MBrace.FsPickler.FsPicklerSerializer */
private class FsPicklerSerializerClass extends Class {
FsPicklerSerializerClass() { this.hasQualifiedName("MBrace.FsPickler.FsPicklerSerializer") }
}
/** `MBrace.FsPickler.FsPicklerSerializer.Deserialize` method */
class FsPicklerSerializerClassDeserializeMethod extends Method, UnsafeDeserializer {
FsPicklerSerializerClassDeserializeMethod() {
this.getDeclaringType().getBaseClass*() instanceof FsPicklerSerializerClass and
this.hasName("Deserialize")
}
}
/** `MBrace.FsPickler.FsPicklerSerializer.DeserializeSequence` method */
class FsPicklerSerializerClassDeserializeSequenceMethod extends Method, UnsafeDeserializer {
FsPicklerSerializerClassDeserializeSequenceMethod() {
this.getDeclaringType().getBaseClass*() instanceof FsPicklerSerializerClass and
this.hasName("DeserializeSequence")
}
}
/** `MBrace.FsPickler.FsPicklerSerializer.DeserializeSifted` method */
class FsPicklerSerializerClasDeserializeSiftedMethod extends Method, UnsafeDeserializer {
FsPicklerSerializerClasDeserializeSiftedMethod() {
this.getDeclaringType().getBaseClass*() instanceof FsPicklerSerializerClass and
this.hasName("DeserializeSifted")
}
}
/** `MBrace.FsPickler.FsPicklerSerializer.UnPickle` method */
class FsPicklerSerializerClassUnPickleMethod extends Method, UnsafeDeserializer {
FsPicklerSerializerClassUnPickleMethod() {
this.getDeclaringType().getBaseClass*() instanceof FsPicklerSerializerClass and
this.hasName("UnPickle")
}
}
/** `MBrace.FsPickler.FsPicklerSerializer.UnPickleSifted` method */
class FsPicklerSerializerClassUnPickleSiftedMethod extends Method, UnsafeDeserializer {
FsPicklerSerializerClassUnPickleSiftedMethod() {
this.getDeclaringType().getBaseClass*() instanceof FsPicklerSerializerClass and
this.hasName("UnPickleSifted")
}
}
/** `MBrace.FsPickler.FsPicklerSerializer.DeserializeUntyped` method */
class FsPicklerSerializerClassDeserializeUntypedMethod extends Method, UnsafeDeserializer {
FsPicklerSerializerClassDeserializeUntypedMethod() {
this.getDeclaringType().getBaseClass*() instanceof FsPicklerSerializerClass and
this.hasName("DeserializeUntyped")
}
}
/** `MBrace.FsPickler.FsPicklerSerializer.DeserializeSequenceUntyped` method */
class FsPicklerSerializerClassDeserializeSequenceUntypedMethod extends Method, UnsafeDeserializer {
FsPicklerSerializerClassDeserializeSequenceUntypedMethod() {
this.getDeclaringType().getBaseClass*() instanceof FsPicklerSerializerClass and
this.hasName("DeserializeSequenceUntyped")
}
}
/** `MBrace.FsPickler.FsPicklerSerializer.UnPickleUntyped` method */
class FsPicklerSerializerClassUnPickleUntypedMethod extends Method, UnsafeDeserializer {
FsPicklerSerializerClassUnPickleUntypedMethod() {
this.getDeclaringType().getBaseClass*() instanceof FsPicklerSerializerClass and
this.hasName("UnPickleUntyped")
}
}
/** MBrace.CsPickler.CsPicklerSerializer */
private class CsPicklerSerializerClass extends Class {
CsPicklerSerializerClass() { this.hasQualifiedName("MBrace.CsPickler.CsPicklerSerializer") }
}
/** `MBrace.FsPickler.CsPicklerSerializer.Deserialize` method */
class CsPicklerSerializerClassDeserializeMethod extends Method, UnsafeDeserializer {
CsPicklerSerializerClassDeserializeMethod() {
this.getDeclaringType().getBaseClass*() instanceof CsPicklerSerializerClass and
this.hasName("Deserialize")
}
}
/** `MBrace.FsPickler.CsPicklerSerializer.UnPickle` method */
class CsPicklerSerializerClassUnPickleMethod extends Method, UnsafeDeserializer {
CsPicklerSerializerClassUnPickleMethod() {
this.getDeclaringType().getBaseClass*() instanceof CsPicklerSerializerClass and
this.hasName("UnPickle")
}
}
/** MBrace.CsPickler.CsPicklerTextSerializer */
private class CsPicklerTextSerializerClass extends Class {
CsPicklerTextSerializerClass() {
this.hasQualifiedName("MBrace.CsPickler.CsPicklerTextSerializer")
}
}
/** `MBrace.FsPickler.CsPicklerTextSerializer.UnPickleOfString` method */
class CsPicklerSerializerClassUnPickleOfStringMethod extends Method, UnsafeDeserializer {
CsPicklerSerializerClassUnPickleOfStringMethod() {
this.getDeclaringType().getBaseClass*() instanceof CsPicklerTextSerializerClass and
this.hasName("UnPickleOfString")
}
}
/** Polenter.Serialization.SharpSerializer */
private class SharpSerializerClass extends Class {
SharpSerializerClass() { this.hasQualifiedName("Polenter.Serialization.SharpSerializer") }
}
/** `Polenter.Serialization.SharpSerializer.Deserialize` method */
class SharpSerializerClassDeserializeMethod extends Method, UnsafeDeserializer {
SharpSerializerClassDeserializeMethod() {
this.getDeclaringType().getBaseClass*() instanceof SharpSerializerClass and
this.hasName("Deserialize")
}
}
/** YamlDotNet.Serialization.Deserializer */
private class YamlDotNetDeserializerClass extends Class {
YamlDotNetDeserializerClass() { this.hasQualifiedName("YamlDotNet.Serialization.Deserializer") }
}
/** `YamlDotNet.Serialization.Deserializer.Deserialize` method */
class YamlDotNetDeserializerClasseserializeMethod extends Method, UnsafeDeserializer {
YamlDotNetDeserializerClasseserializeMethod() {
exists(YamlDotNetDeserializerClass c |
this.getDeclaringType().getBaseClass*() = c and
this.hasName("Deserialize") and
c.getALocation().(Assembly).getVersion().getMajor() < 5
)
}
}
/** `Newtonsoft.Json.JsonConvert.DeserializeObject` method */
class NewtonsoftJsonConvertClassDeserializeObjectMethod extends Method, UnsafeDeserializer {
NewtonsoftJsonConvertClassDeserializeObjectMethod() {
this.getDeclaringType() instanceof JsonConvertClass and
this.hasName("DeserializeObject") and
this.isStatic()
}
}

View File

@@ -0,0 +1,12 @@
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;
class BadBinaryFormatter
{
public static object Deserialize(Stream s)
{
var ds = new BinaryFormatter();
// BAD
return ds.Deserialize(s);
}
}

View File

@@ -0,0 +1,13 @@
using System.Runtime.Serialization.Json;
using System.IO;
using System;
class BadDataContractJsonSerializer
{
public static object Deserialize(Type type, Stream s)
{
var ds = new DataContractJsonSerializer(type);
// BAD
return ds.ReadObject(s);
}
}

View File

@@ -0,0 +1,13 @@
using System.Runtime.Serialization.Json;
using System.IO;
using System;
class GoodDataContractJsonSerializer
{
public static object Deserialize(Stream s)
{
// Good: type is hardcoded
var ds = new DataContractJsonSerializer(typeof(GoodDataContractJsonSerializer));
return ds.ReadObject(s);
}
}

View File

@@ -0,0 +1,13 @@
using System.Runtime.Serialization;
using System.IO;
using System;
class BadDataContractSerializer
{
public static object Deserialize(Type type, Stream s)
{
var ds = new DataContractSerializer(type);
// BAD
return ds.ReadObject(s);
}
}

View File

@@ -0,0 +1,13 @@
using System.Runtime.Serialization;
using System.IO;
using System;
class GoodDataContractSerializer
{
public static object Deserialize(Stream s)
{
// Good: type is hardcoded
var ds = new DataContractSerializer(typeof(GoodDataContractSerializer));
return ds.ReadObject(s);
}
}

View File

@@ -0,0 +1,17 @@
using System.Resources;
using System.IO;
using System;
class BadResourceReader
{
public static void Deserialize(Stream s)
{
var ds = new ResourceReader(s);
// BAD
var dict = ds.GetEnumerator();
while (dict.MoveNext())
Console.WriteLine(" {0}: '{1}' (Type {2})",
dict.Key, dict.Value, dict.Value.GetType().Name);
ds.Close();
}
}

View File

@@ -1 +1,7 @@
| BinaryFormatterBad.cs:10:16:10:32 | call to method Deserialize | Unsafe deserializer is used. Make sure the value being deserialized comes from a trusted source. |
| DataContractJsonSerializerBad.cs:11:16:11:31 | call to method ReadObject | Unsafe deserializer is used. Make sure the value being deserialized comes from a trusted source. |
| DataContractSerializerBad.cs:11:16:11:31 | call to method ReadObject | Unsafe deserializer is used. Make sure the value being deserialized comes from a trusted source. |
| ResourceReaderBad.cs:9:18:9:38 | object creation of type ResourceReader | Unsafe deserializer is used. Make sure the value being deserialized comes from a trusted source. |
| UnsafeDeserializationBad.cs:9:16:9:38 | call to method DeserializeObject | Unsafe deserializer is used. Make sure the value being deserialized comes from a trusted source. |
| XmlObjectSerializerBad.cs:11:16:11:31 | call to method ReadObject | Unsafe deserializer is used. Make sure the value being deserialized comes from a trusted source. |
| XmlSerializerBad.cs:11:16:11:32 | call to method Deserialize | Unsafe deserializer is used. Make sure the value being deserialized comes from a trusted source. |

View File

@@ -0,0 +1,13 @@
using System.Runtime.Serialization;
using System.IO;
using System;
class BadXmlObjectSerializer
{
public static object Deserialize(Type type, Stream s)
{
XmlObjectSerializer ds = new DataContractSerializer(type);
// BAD
return ds.ReadObject(s);
}
}

View File

@@ -0,0 +1,13 @@
using System.Runtime.Serialization;
using System.IO;
using System;
class GoodXmlObjectSerializer
{
public static object Deserialize(Stream s)
{
// Good: type is hardcoded
XmlObjectSerializer ds = new DataContractSerializer(typeof(GoodXmlObjectSerializer));
return ds.ReadObject(s);
}
}

View File

@@ -0,0 +1,13 @@
using System.Xml.Serialization;
using System.IO;
using System;
class BadXmlSerializer
{
public static object Deserialize(Type type, Stream s)
{
var ds = new XmlSerializer(type);
// BAD
return ds.Deserialize(s);
}
}

View File

@@ -0,0 +1,13 @@
using System.Xml.Serialization;
using System.IO;
using System;
class GoodXmlSerializer
{
public static object Deserialize(Stream s)
{
// Good: type is hardcoded
var ds = new XmlSerializer(typeof(GoodXmlSerializer));
return ds.Deserialize(s);
}
}

View File

@@ -1 +1 @@
semmle-extractor-options: /r:System.Runtime.Extensions.dll /r:System.IO.FileSystem.dll /r:System.Collections.Specialized.dll ${testdir}/../../../../resources/stubs/System.Web.cs
semmle-extractor-options: /r:System.Private.Xml.dll /r:System.Xml.ReaderWriter.dll /r:System.Private.DataContractSerialization.dll /r:System.Runtime.Serialization.Formatters.dll /r:System.Runtime.Extensions.dll /r:System.IO.FileSystem.dll /r:System.Collections.Specialized.dll ${testdir}/../../../../resources/stubs/System.Web.cs

View File

@@ -0,0 +1,14 @@
using System.Web.UI.WebControls;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;
using System.Text;
class BadBinaryFormatter
{
public static object Deserialize(TextBox textBox)
{
var ds = new BinaryFormatter();
// BAD
return ds.Deserialize(new MemoryStream(Encoding.UTF8.GetBytes(textBox.Text)));
}
}

View File

@@ -0,0 +1,13 @@
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;
using System.Text;
class GoodBinaryFormatter
{
public static object Deserialize()
{
var ds = new BinaryFormatter();
// GOOD
return ds.Deserialize(new MemoryStream(Encoding.UTF8.GetBytes("hardcoded")));
}
}

View File

@@ -0,0 +1,15 @@
using System.Web.UI.WebControls;
using System.Runtime.Serialization.Json;
using System.IO;
using System.Text;
using System;
class BadDataContractJsonSerializer
{
public static object Deserialize(TextBox type, TextBox data)
{
var ds = new DataContractJsonSerializer(Type.GetType(type.Text));
// BAD
return ds.ReadObject(new MemoryStream(Encoding.UTF8.GetBytes(data.Text)));
}
}

View File

@@ -0,0 +1,22 @@
using System.Web.UI.WebControls;
using System.Runtime.Serialization.Json;
using System.IO;
using System.Text;
using System;
class GoodDataContractJsonSerializer
{
public static object Deserialize1(TextBox data)
{
// GOOD
var ds = new DataContractJsonSerializer(typeof(GoodDataContractJsonSerializer));
return ds.ReadObject(new MemoryStream(Encoding.UTF8.GetBytes(data.Text)));
}
public static object Deserialize2(TextBox type)
{
var ds = new DataContractJsonSerializer(Type.GetType(type.Text));
// GOOD
return ds.ReadObject(new MemoryStream(Encoding.UTF8.GetBytes("hardcoded")));
}
}

View File

@@ -0,0 +1,15 @@
using System.Web.UI.WebControls;
using System.Runtime.Serialization;
using System.IO;
using System.Text;
using System;
class BadDataContractSerializer
{
public static object Deserialize(TextBox type, TextBox data)
{
var ds = new DataContractSerializer(Type.GetType(type.Text));
// BAD
return ds.ReadObject(new MemoryStream(Encoding.UTF8.GetBytes(data.Text)));
}
}

View File

@@ -0,0 +1,22 @@
using System.Web.UI.WebControls;
using System.Runtime.Serialization;
using System.IO;
using System.Text;
using System;
class GoodDataContractSerializer
{
public static object Deserialize1(TextBox data)
{
// GOOD
var ds = new DataContractSerializer(typeof(GoodDataContractSerializer));
return ds.ReadObject(new MemoryStream(Encoding.UTF8.GetBytes(data.Text)));
}
public static object Deserialize2(TextBox type)
{
var ds = new DataContractSerializer(Type.GetType(type.Text));
// GOOD
return ds.ReadObject(new MemoryStream(Encoding.UTF8.GetBytes("hardcoded")));
}
}

View File

@@ -0,0 +1,19 @@
using System.Web.UI.WebControls;
using System.Resources;
using System.IO;
using System.Text;
using System;
class BadResourceReader
{
public static void Deserialize(TextBox data)
{
var ds = new ResourceReader(new MemoryStream(Encoding.UTF8.GetBytes(data.Text)));
// BAD
var dict = ds.GetEnumerator();
while (dict.MoveNext())
Console.WriteLine(" {0}: '{1}' (Type {2})",
dict.Key, dict.Value, dict.Value.GetType().Name);
ds.Close();
}
}

View File

@@ -0,0 +1,19 @@
using System.Web.UI.WebControls;
using System.Resources;
using System.IO;
using System.Text;
using System;
class GoodResourceReader
{
public static void Deserialize(TextBox data)
{
// GOOD
var ds = new ResourceReader(new MemoryStream(Encoding.UTF8.GetBytes("hardcoded")));
var dict = ds.GetEnumerator();
while (dict.MoveNext())
Console.WriteLine(" {0}: '{1}' (Type {2})",
dict.Key, dict.Value, dict.Value.GetType().Name);
ds.Close();
}
}

View File

@@ -1,7 +1,55 @@
edges
| BinaryFormatterUntrustedInputBad.cs:12:48:12:83 | call to method GetBytes : Byte[] | BinaryFormatterUntrustedInputBad.cs:12:31:12:84 | object creation of type MemoryStream |
| BinaryFormatterUntrustedInputBad.cs:12:71:12:77 | access to parameter textBox : TextBox | BinaryFormatterUntrustedInputBad.cs:12:71:12:82 | access to property Text : String |
| BinaryFormatterUntrustedInputBad.cs:12:71:12:82 | access to property Text : String | BinaryFormatterUntrustedInputBad.cs:12:48:12:83 | call to method GetBytes : Byte[] |
| DataContractJsonSerializerUntrustedInputBad.cs:13:47:13:79 | call to method GetBytes : Byte[] | DataContractJsonSerializerUntrustedInputBad.cs:13:30:13:80 | object creation of type MemoryStream |
| DataContractJsonSerializerUntrustedInputBad.cs:13:70:13:73 | access to parameter data : TextBox | DataContractJsonSerializerUntrustedInputBad.cs:13:70:13:78 | access to property Text : String |
| DataContractJsonSerializerUntrustedInputBad.cs:13:70:13:78 | access to property Text : String | DataContractJsonSerializerUntrustedInputBad.cs:13:47:13:79 | call to method GetBytes : Byte[] |
| DataContractSerializerUntrustedInputBad.cs:13:47:13:79 | call to method GetBytes : Byte[] | DataContractSerializerUntrustedInputBad.cs:13:30:13:80 | object creation of type MemoryStream |
| DataContractSerializerUntrustedInputBad.cs:13:70:13:73 | access to parameter data : TextBox | DataContractSerializerUntrustedInputBad.cs:13:70:13:78 | access to property Text : String |
| DataContractSerializerUntrustedInputBad.cs:13:70:13:78 | access to property Text : String | DataContractSerializerUntrustedInputBad.cs:13:47:13:79 | call to method GetBytes : Byte[] |
| ResourceReaderUntrustedInputBad.cs:11:54:11:86 | call to method GetBytes : Byte[] | ResourceReaderUntrustedInputBad.cs:11:37:11:87 | object creation of type MemoryStream |
| ResourceReaderUntrustedInputBad.cs:11:77:11:80 | access to parameter data : TextBox | ResourceReaderUntrustedInputBad.cs:11:77:11:85 | access to property Text : String |
| ResourceReaderUntrustedInputBad.cs:11:77:11:85 | access to property Text : String | ResourceReaderUntrustedInputBad.cs:11:54:11:86 | call to method GetBytes : Byte[] |
| UnsafeDeserializationUntrustedInputBad.cs:10:37:10:43 | access to parameter textBox : TextBox | UnsafeDeserializationUntrustedInputBad.cs:10:37:10:48 | access to property Text |
| XmlObjectSerializerUntrustedInputBad.cs:13:47:13:79 | call to method GetBytes : Byte[] | XmlObjectSerializerUntrustedInputBad.cs:13:30:13:80 | object creation of type MemoryStream |
| XmlObjectSerializerUntrustedInputBad.cs:13:70:13:73 | access to parameter data : TextBox | XmlObjectSerializerUntrustedInputBad.cs:13:70:13:78 | access to property Text : String |
| XmlObjectSerializerUntrustedInputBad.cs:13:70:13:78 | access to property Text : String | XmlObjectSerializerUntrustedInputBad.cs:13:47:13:79 | call to method GetBytes : Byte[] |
| XmlSerializerUntrustedInputBad.cs:13:48:13:80 | call to method GetBytes : Byte[] | XmlSerializerUntrustedInputBad.cs:13:31:13:81 | object creation of type MemoryStream |
| XmlSerializerUntrustedInputBad.cs:13:71:13:74 | access to parameter data : TextBox | XmlSerializerUntrustedInputBad.cs:13:71:13:79 | access to property Text : String |
| XmlSerializerUntrustedInputBad.cs:13:71:13:79 | access to property Text : String | XmlSerializerUntrustedInputBad.cs:13:48:13:80 | call to method GetBytes : Byte[] |
nodes
| BinaryFormatterUntrustedInputBad.cs:12:31:12:84 | object creation of type MemoryStream | semmle.label | object creation of type MemoryStream |
| BinaryFormatterUntrustedInputBad.cs:12:48:12:83 | call to method GetBytes : Byte[] | semmle.label | call to method GetBytes : Byte[] |
| BinaryFormatterUntrustedInputBad.cs:12:71:12:77 | access to parameter textBox : TextBox | semmle.label | access to parameter textBox : TextBox |
| BinaryFormatterUntrustedInputBad.cs:12:71:12:82 | access to property Text : String | semmle.label | access to property Text : String |
| DataContractJsonSerializerUntrustedInputBad.cs:13:30:13:80 | object creation of type MemoryStream | semmle.label | object creation of type MemoryStream |
| DataContractJsonSerializerUntrustedInputBad.cs:13:47:13:79 | call to method GetBytes : Byte[] | semmle.label | call to method GetBytes : Byte[] |
| DataContractJsonSerializerUntrustedInputBad.cs:13:70:13:73 | access to parameter data : TextBox | semmle.label | access to parameter data : TextBox |
| DataContractJsonSerializerUntrustedInputBad.cs:13:70:13:78 | access to property Text : String | semmle.label | access to property Text : String |
| DataContractSerializerUntrustedInputBad.cs:13:30:13:80 | object creation of type MemoryStream | semmle.label | object creation of type MemoryStream |
| DataContractSerializerUntrustedInputBad.cs:13:47:13:79 | call to method GetBytes : Byte[] | semmle.label | call to method GetBytes : Byte[] |
| DataContractSerializerUntrustedInputBad.cs:13:70:13:73 | access to parameter data : TextBox | semmle.label | access to parameter data : TextBox |
| DataContractSerializerUntrustedInputBad.cs:13:70:13:78 | access to property Text : String | semmle.label | access to property Text : String |
| ResourceReaderUntrustedInputBad.cs:11:37:11:87 | object creation of type MemoryStream | semmle.label | object creation of type MemoryStream |
| ResourceReaderUntrustedInputBad.cs:11:54:11:86 | call to method GetBytes : Byte[] | semmle.label | call to method GetBytes : Byte[] |
| ResourceReaderUntrustedInputBad.cs:11:77:11:80 | access to parameter data : TextBox | semmle.label | access to parameter data : TextBox |
| ResourceReaderUntrustedInputBad.cs:11:77:11:85 | access to property Text : String | semmle.label | access to property Text : String |
| UnsafeDeserializationUntrustedInputBad.cs:10:37:10:43 | access to parameter textBox : TextBox | semmle.label | access to parameter textBox : TextBox |
| UnsafeDeserializationUntrustedInputBad.cs:10:37:10:48 | access to property Text | semmle.label | access to property Text |
| XmlObjectSerializerUntrustedInputBad.cs:13:30:13:80 | object creation of type MemoryStream | semmle.label | object creation of type MemoryStream |
| XmlObjectSerializerUntrustedInputBad.cs:13:47:13:79 | call to method GetBytes : Byte[] | semmle.label | call to method GetBytes : Byte[] |
| XmlObjectSerializerUntrustedInputBad.cs:13:70:13:73 | access to parameter data : TextBox | semmle.label | access to parameter data : TextBox |
| XmlObjectSerializerUntrustedInputBad.cs:13:70:13:78 | access to property Text : String | semmle.label | access to property Text : String |
| XmlSerializerUntrustedInputBad.cs:13:31:13:81 | object creation of type MemoryStream | semmle.label | object creation of type MemoryStream |
| XmlSerializerUntrustedInputBad.cs:13:48:13:80 | call to method GetBytes : Byte[] | semmle.label | call to method GetBytes : Byte[] |
| XmlSerializerUntrustedInputBad.cs:13:71:13:74 | access to parameter data : TextBox | semmle.label | access to parameter data : TextBox |
| XmlSerializerUntrustedInputBad.cs:13:71:13:79 | access to property Text : String | semmle.label | access to property Text : String |
#select
| UnsafeDeserializationUntrustedInputBad.cs:10:37:10:48 | access to property Text | UnsafeDeserializationUntrustedInputBad.cs:10:37:10:43 | access to parameter textBox : TextBox | UnsafeDeserializationUntrustedInputBad.cs:10:37:10:48 | access to property Text | $@ flows to unsafe deserializer. | UnsafeDeserializationUntrustedInputBad.cs:10:37:10:43 | access to parameter textBox | User-provided data |
| BinaryFormatterUntrustedInputBad.cs:12:31:12:84 | object creation of type MemoryStream | BinaryFormatterUntrustedInputBad.cs:12:71:12:77 | access to parameter textBox : TextBox | BinaryFormatterUntrustedInputBad.cs:12:31:12:84 | object creation of type MemoryStream | $@ flows to unsafe deserializer. | BinaryFormatterUntrustedInputBad.cs:12:71:12:77 | access to parameter textBox : TextBox | User-provided data |
| DataContractJsonSerializerUntrustedInputBad.cs:13:30:13:80 | object creation of type MemoryStream | DataContractJsonSerializerUntrustedInputBad.cs:13:70:13:73 | access to parameter data : TextBox | DataContractJsonSerializerUntrustedInputBad.cs:13:30:13:80 | object creation of type MemoryStream | $@ flows to unsafe deserializer. | DataContractJsonSerializerUntrustedInputBad.cs:13:70:13:73 | access to parameter data : TextBox | User-provided data |
| DataContractSerializerUntrustedInputBad.cs:13:30:13:80 | object creation of type MemoryStream | DataContractSerializerUntrustedInputBad.cs:13:70:13:73 | access to parameter data : TextBox | DataContractSerializerUntrustedInputBad.cs:13:30:13:80 | object creation of type MemoryStream | $@ flows to unsafe deserializer. | DataContractSerializerUntrustedInputBad.cs:13:70:13:73 | access to parameter data : TextBox | User-provided data |
| ResourceReaderUntrustedInputBad.cs:11:37:11:87 | object creation of type MemoryStream | ResourceReaderUntrustedInputBad.cs:11:77:11:80 | access to parameter data : TextBox | ResourceReaderUntrustedInputBad.cs:11:37:11:87 | object creation of type MemoryStream | $@ flows to unsafe deserializer. | ResourceReaderUntrustedInputBad.cs:11:77:11:80 | access to parameter data : TextBox | User-provided data |
| UnsafeDeserializationUntrustedInputBad.cs:10:37:10:48 | access to property Text | UnsafeDeserializationUntrustedInputBad.cs:10:37:10:43 | access to parameter textBox : TextBox | UnsafeDeserializationUntrustedInputBad.cs:10:37:10:48 | access to property Text | $@ flows to unsafe deserializer. | UnsafeDeserializationUntrustedInputBad.cs:10:37:10:43 | access to parameter textBox : TextBox | User-provided data |
| XmlObjectSerializerUntrustedInputBad.cs:13:30:13:80 | object creation of type MemoryStream | XmlObjectSerializerUntrustedInputBad.cs:13:70:13:73 | access to parameter data : TextBox | XmlObjectSerializerUntrustedInputBad.cs:13:30:13:80 | object creation of type MemoryStream | $@ flows to unsafe deserializer. | XmlObjectSerializerUntrustedInputBad.cs:13:70:13:73 | access to parameter data : TextBox | User-provided data |
| XmlSerializerUntrustedInputBad.cs:13:31:13:81 | object creation of type MemoryStream | XmlSerializerUntrustedInputBad.cs:13:71:13:74 | access to parameter data : TextBox | XmlSerializerUntrustedInputBad.cs:13:31:13:81 | object creation of type MemoryStream | $@ flows to unsafe deserializer. | XmlSerializerUntrustedInputBad.cs:13:71:13:74 | access to parameter data : TextBox | User-provided data |

View File

@@ -6,7 +6,7 @@ class Good
public static object Deserialize(TextBox textBox)
{
JavaScriptSerializer sr = new JavaScriptSerializer();
// GOOD
// GOOD: no unsafe type resolver
return sr.DeserializeObject(textBox.Text);
}
}

View File

@@ -0,0 +1,15 @@
using System.Web.UI.WebControls;
using System.Runtime.Serialization;
using System.IO;
using System.Text;
using System;
class BadXmlObjectSerializer
{
public static object Deserialize(TextBox type, TextBox data)
{
XmlObjectSerializer ds = new DataContractSerializer(Type.GetType(type.Text));
// BAD
return ds.ReadObject(new MemoryStream(Encoding.UTF8.GetBytes(data.Text)));
}
}

View File

@@ -0,0 +1,22 @@
using System.Web.UI.WebControls;
using System.Runtime.Serialization;
using System.IO;
using System.Text;
using System;
class GoodXmlObjectSerializer
{
public static object Deserialize1(TextBox data)
{
// GOOD
XmlObjectSerializer ds = new DataContractSerializer(typeof(GoodXmlObjectSerializer));
return ds.ReadObject(new MemoryStream(Encoding.UTF8.GetBytes(data.Text)));
}
public static object Deserialize2(TextBox type)
{
XmlObjectSerializer ds = new DataContractSerializer(Type.GetType(type.Text));
// GOOD
return ds.ReadObject(new MemoryStream(Encoding.UTF8.GetBytes("hardcoded")));
}
}

View File

@@ -0,0 +1,15 @@
using System.Web.UI.WebControls;
using System.Xml.Serialization;
using System.IO;
using System.Text;
using System;
class BadXmlSerializer
{
public static object Deserialize(TextBox type, TextBox data)
{
var ds = new XmlSerializer(Type.GetType(type.Text));
// BAD
return ds.Deserialize(new MemoryStream(Encoding.UTF8.GetBytes(data.Text)));
}
}

View File

@@ -0,0 +1,22 @@
using System.Web.UI.WebControls;
using System.Xml.Serialization;
using System.IO;
using System.Text;
using System;
class GoodXmlSerializer
{
public static object Deserialize1(TextBox data)
{
// GOOD
var ds = new XmlSerializer(typeof(GoodXmlSerializer));
return ds.Deserialize(new MemoryStream(Encoding.UTF8.GetBytes(data.Text)));
}
public static object Deserialize2(TextBox type)
{
var ds = new XmlSerializer(Type.GetType(type.Text));
// GOOD
return ds.Deserialize(new MemoryStream(Encoding.UTF8.GetBytes("hardcoded")));
}
}

View File

@@ -1 +1 @@
semmle-extractor-options: /r:System.Runtime.Extensions.dll /r:System.IO.FileSystem.dll /r:System.Collections.Specialized.dll ${testdir}/../../../../resources/stubs/System.Web.cs
semmle-extractor-options: /r:System.Private.Xml.dll /r:System.Xml.ReaderWriter.dll /r:System.Private.DataContractSerialization.dll /r:System.Runtime.Serialization.Formatters.dll /r:System.Runtime.Extensions.dll /r:System.IO.FileSystem.dll /r:System.Collections.Specialized.dll ${testdir}/../../../../resources/stubs/System.Web.cs