Merge pull request #7348 from michaelnebel/csharp-mad-as-csv-json

C#: Convert flow summaries for JSon.NET
This commit is contained in:
Michael Nebel
2021-12-13 11:57:55 +01:00
committed by GitHub
7 changed files with 121 additions and 97 deletions

View File

@@ -97,6 +97,7 @@ private module Frameworks {
private import semmle.code.csharp.frameworks.system.Web
private import semmle.code.csharp.frameworks.system.collections.Generic
private import semmle.code.csharp.frameworks.system.web.ui.WebControls
private import semmle.code.csharp.frameworks.JsonNET
}
/**

View File

@@ -21,7 +21,6 @@ private import semmle.code.csharp.dataflow.internal.DataFlowPublic
private import semmle.code.csharp.dataflow.internal.DelegateDataFlow
// import `LibraryTypeDataFlow` definitions from other files to avoid potential reevaluation
private import semmle.code.csharp.frameworks.EntityFramework
private import semmle.code.csharp.frameworks.JsonNET
private import FlowSummary
private newtype TAccessPath =

View File

@@ -3,7 +3,7 @@
*/
import csharp
private import semmle.code.csharp.dataflow.LibraryTypeDataFlow
private import semmle.code.csharp.dataflow.ExternalFlow
/** Definitions relating to the `Json.NET` package. */
module JsonNET {
@@ -31,15 +31,9 @@ module JsonNET {
}
/** The class `Newtonsoft.Json.JsonConvert`. */
class JsonConvertClass extends JsonClass, LibraryTypeDataFlow {
class JsonConvertClass extends JsonClass {
JsonConvertClass() { this.hasName("JsonConvert") }
/** Gets a `ToString` method. */
private Method getAToStringMethod() {
result = this.getAMethod("ToString") and
result.isStatic()
}
/** Gets a `Deserialize` method. */
Method getADeserializeMethod() {
result = this.getAMethod() and
@@ -51,39 +45,73 @@ module JsonNET {
result = this.getAMethod() and
result.getName().matches("Serialize%")
}
}
private Method getAPopulateMethod() {
result = this.getAMethod() and
result.getName().matches("Populate%")
}
override predicate callableFlow(
CallableFlowSource source, CallableFlowSink sink, SourceDeclarationCallable c,
boolean preservesValue
) {
// ToString methods
c = this.getAToStringMethod() and
preservesValue = false and
source = any(CallableFlowSourceArg arg | arg.getArgumentIndex() = 0) and
sink instanceof CallableFlowSinkReturn
or
// Deserialize methods
c = this.getADeserializeMethod() and
preservesValue = false and
source = any(CallableFlowSourceArg arg | arg.getArgumentIndex() = 0) and
sink instanceof CallableFlowSinkReturn
or
// Serialize methods
c = this.getASerializeMethod() and
preservesValue = false and
source = any(CallableFlowSourceArg arg | arg.getArgumentIndex() = 0) and
sink instanceof CallableFlowSinkReturn
or
// Populate methods
c = this.getAPopulateMethod() and
preservesValue = false and
source = any(CallableFlowSourceArg arg | arg.getArgumentIndex() = 0) and
sink = any(CallableFlowSinkArg arg | arg.getArgumentIndex() = 1)
/** Data flow for `Newtonsoft.Json.JsonConvert`. */
private class JsonConvertClassFlowModelCsv extends SummaryModelCsv {
override predicate row(string row) {
row =
[
"Newtonsoft.Json;JsonConvert;false;DeserializeAnonymousType<>;(System.String,T);;Argument[0];ReturnValue;taint",
"Newtonsoft.Json;JsonConvert;false;DeserializeAnonymousType<>;(System.String,T,Newtonsoft.Json.JsonSerializerSettings);;Argument[0];ReturnValue;taint",
"Newtonsoft.Json;JsonConvert;false;DeserializeObject;(System.String);;Argument[0];ReturnValue;taint",
"Newtonsoft.Json;JsonConvert;false;DeserializeObject;(System.String,Newtonsoft.Json.JsonSerializerSettings);;Argument[0];ReturnValue;taint",
"Newtonsoft.Json;JsonConvert;false;DeserializeObject;(System.String,System.Type);;Argument[0];ReturnValue;taint",
"Newtonsoft.Json;JsonConvert;false;DeserializeObject;(System.String,System.Type,Newtonsoft.Json.JsonConverter[]);;Argument[0];ReturnValue;taint",
"Newtonsoft.Json;JsonConvert;false;DeserializeObject;(System.String,System.Type,Newtonsoft.Json.JsonSerializerSettings);;Argument[0];ReturnValue;taint",
"Newtonsoft.Json;JsonConvert;false;DeserializeObject<>;(System.String);;Argument[0];ReturnValue;taint",
"Newtonsoft.Json;JsonConvert;false;DeserializeObject<>;(System.String,Newtonsoft.Json.JsonConverter[]);;Argument[0];ReturnValue;taint",
"Newtonsoft.Json;JsonConvert;false;DeserializeObject<>;(System.String,Newtonsoft.Json.JsonSerializerSettings);;Argument[0];ReturnValue;taint",
"Newtonsoft.Json;JsonConvert;false;DeserializeXNode;(System.String);;Argument[0];ReturnValue;taint",
"Newtonsoft.Json;JsonConvert;false;DeserializeXNode;(System.String,System.String);;Argument[0];ReturnValue;taint",
"Newtonsoft.Json;JsonConvert;false;DeserializeXNode;(System.String,System.String,System.Boolean);;Argument[0];ReturnValue;taint",
"Newtonsoft.Json;JsonConvert;false;DeserializeXNode;(System.String,System.String,System.Boolean,System.Boolean);;Argument[0];ReturnValue;taint",
"Newtonsoft.Json;JsonConvert;false;DeserializeXmlNode;(System.String);;Argument[0];ReturnValue;taint",
"Newtonsoft.Json;JsonConvert;false;DeserializeXmlNode;(System.String,System.String);;Argument[0];ReturnValue;taint",
"Newtonsoft.Json;JsonConvert;false;DeserializeXmlNode;(System.String,System.String,System.Boolean);;Argument[0];ReturnValue;taint",
"Newtonsoft.Json;JsonConvert;false;DeserializeXmlNode;(System.String,System.String,System.Boolean,System.Boolean);;Argument[0];ReturnValue;taint",
"Newtonsoft.Json;JsonConvert;false;PopulateObject;(System.String,System.Object);;Argument[0];Argument[1];taint",
"Newtonsoft.Json;JsonConvert;false;PopulateObject;(System.String,System.Object,Newtonsoft.Json.JsonSerializerSettings);;Argument[0];Argument[1];taint",
"Newtonsoft.Json;JsonConvert;false;SerializeObject;(System.Object);;Argument[0];ReturnValue;taint",
"Newtonsoft.Json;JsonConvert;false;SerializeObject;(System.Object,Newtonsoft.Json.Formatting);;Argument[0];ReturnValue;taint",
"Newtonsoft.Json;JsonConvert;false;SerializeObject;(System.Object,Newtonsoft.Json.Formatting,Newtonsoft.Json.JsonConverter[]);;Argument[0];ReturnValue;taint",
"Newtonsoft.Json;JsonConvert;false;SerializeObject;(System.Object,Newtonsoft.Json.Formatting,Newtonsoft.Json.JsonSerializerSettings);;Argument[0];ReturnValue;taint",
"Newtonsoft.Json;JsonConvert;false;SerializeObject;(System.Object,Newtonsoft.Json.JsonConverter[]);;Argument[0];ReturnValue;taint",
"Newtonsoft.Json;JsonConvert;false;SerializeObject;(System.Object,Newtonsoft.Json.JsonSerializerSettings);;Argument[0];ReturnValue;taint",
"Newtonsoft.Json;JsonConvert;false;SerializeObject;(System.Object,System.Type,Newtonsoft.Json.Formatting,Newtonsoft.Json.JsonSerializerSettings);;Argument[0];ReturnValue;taint",
"Newtonsoft.Json;JsonConvert;false;SerializeObject;(System.Object,System.Type,Newtonsoft.Json.JsonSerializerSettings);;Argument[0];ReturnValue;taint",
"Newtonsoft.Json;JsonConvert;false;SerializeXNode;(System.Xml.Linq.XObject);;Argument[0];ReturnValue;taint",
"Newtonsoft.Json;JsonConvert;false;SerializeXNode;(System.Xml.Linq.XObject,Newtonsoft.Json.Formatting);;Argument[0];ReturnValue;taint",
"Newtonsoft.Json;JsonConvert;false;SerializeXNode;(System.Xml.Linq.XObject,Newtonsoft.Json.Formatting,System.Boolean);;Argument[0];ReturnValue;taint",
"Newtonsoft.Json;JsonConvert;false;SerializeXmlNode;(System.Xml.XmlNode);;Argument[0];ReturnValue;taint",
"Newtonsoft.Json;JsonConvert;false;SerializeXmlNode;(System.Xml.XmlNode,Newtonsoft.Json.Formatting);;Argument[0];ReturnValue;taint",
"Newtonsoft.Json;JsonConvert;false;SerializeXmlNode;(System.Xml.XmlNode,Newtonsoft.Json.Formatting,System.Boolean);;Argument[0];ReturnValue;taint",
"Newtonsoft.Json;JsonConvert;false;ToString;(System.Boolean);;Argument[0];ReturnValue;taint",
"Newtonsoft.Json;JsonConvert;false;ToString;(System.Byte);;Argument[0];ReturnValue;taint",
"Newtonsoft.Json;JsonConvert;false;ToString;(System.Char);;Argument[0];ReturnValue;taint",
"Newtonsoft.Json;JsonConvert;false;ToString;(System.DateTime);;Argument[0];ReturnValue;taint",
"Newtonsoft.Json;JsonConvert;false;ToString;(System.DateTime,Newtonsoft.Json.DateFormatHandling,Newtonsoft.Json.DateTimeZoneHandling);;Argument[0];ReturnValue;taint",
"Newtonsoft.Json;JsonConvert;false;ToString;(System.DateTimeOffset);;Argument[0];ReturnValue;taint",
"Newtonsoft.Json;JsonConvert;false;ToString;(System.DateTimeOffset,Newtonsoft.Json.DateFormatHandling);;Argument[0];ReturnValue;taint",
"Newtonsoft.Json;JsonConvert;false;ToString;(System.Decimal);;Argument[0];ReturnValue;taint",
"Newtonsoft.Json;JsonConvert;false;ToString;(System.Double);;Argument[0];ReturnValue;taint",
"Newtonsoft.Json;JsonConvert;false;ToString;(System.Enum);;Argument[0];ReturnValue;taint",
"Newtonsoft.Json;JsonConvert;false;ToString;(System.Guid);;Argument[0];ReturnValue;taint",
"Newtonsoft.Json;JsonConvert;false;ToString;(System.Int16);;Argument[0];ReturnValue;taint",
"Newtonsoft.Json;JsonConvert;false;ToString;(System.Int32);;Argument[0];ReturnValue;taint",
"Newtonsoft.Json;JsonConvert;false;ToString;(System.Int64);;Argument[0];ReturnValue;taint",
"Newtonsoft.Json;JsonConvert;false;ToString;(System.Object);;Argument[0];ReturnValue;taint",
"Newtonsoft.Json;JsonConvert;false;ToString;(System.SByte);;Argument[0];ReturnValue;taint",
"Newtonsoft.Json;JsonConvert;false;ToString;(System.Single);;Argument[0];ReturnValue;taint",
"Newtonsoft.Json;JsonConvert;false;ToString;(System.String);;Argument[0];ReturnValue;taint",
"Newtonsoft.Json;JsonConvert;false;ToString;(System.String,System.Char);;Argument[0];ReturnValue;taint",
"Newtonsoft.Json;JsonConvert;false;ToString;(System.String,System.Char,Newtonsoft.Json.StringEscapeHandling);;Argument[0];ReturnValue;taint",
"Newtonsoft.Json;JsonConvert;false;ToString;(System.TimeSpan);;Argument[0];ReturnValue;taint",
"Newtonsoft.Json;JsonConvert;false;ToString;(System.UInt16);;Argument[0];ReturnValue;taint",
"Newtonsoft.Json;JsonConvert;false;ToString;(System.UInt32);;Argument[0];ReturnValue;taint",
"Newtonsoft.Json;JsonConvert;false;ToString;(System.UInt64);;Argument[0];ReturnValue;taint",
"Newtonsoft.Json;JsonConvert;false;ToString;(System.Uri);;Argument[0];ReturnValue;taint",
]
}
}
@@ -137,7 +165,7 @@ module JsonNET {
}
/** The class `NewtonSoft.Json.JsonSerializer`. */
class JsonSerializerClass extends JsonClass, LibraryTypeDataFlow {
class JsonSerializerClass extends JsonClass {
JsonSerializerClass() { this.hasName("JsonSerializer") }
/** Gets the method for `JsonSerializer.Serialize`. */
@@ -145,22 +173,21 @@ module JsonNET {
/** Gets the method for `JsonSerializer.Deserialize`. */
Method getDeserializeMethod() { result = this.getAMethod("Deserialize") }
}
override predicate callableFlow(
CallableFlowSource source, CallableFlowSink sink, SourceDeclarationCallable c,
boolean preservesValue
) {
// Serialize
c = this.getSerializeMethod() and
preservesValue = false and
source = any(CallableFlowSourceArg arg | arg.getArgumentIndex() = 1) and
sink = any(CallableFlowSinkArg arg | arg.getArgumentIndex() = 0)
or
// Deserialize
c = this.getDeserializeMethod() and
preservesValue = false and
source = any(CallableFlowSourceArg arg | arg.getArgumentIndex() = 0) and
sink instanceof CallableFlowSinkReturn
/** Data flow for `NewtonSoft.Json.JSonSerializer`. */
private class JsonSerializerClassFlowModelCsv extends SummaryModelCsv {
override predicate row(string row) {
row =
[
"Newtonsoft.Json;JsonSerializer;false;Deserialize;(Newtonsoft.Json.JsonReader);;Argument[0];ReturnValue;taint",
"Newtonsoft.Json;JsonSerializer;false;Deserialize;(Newtonsoft.Json.JsonReader,System.Type);;Argument[0];ReturnValue;taint",
"Newtonsoft.Json;JsonSerializer;false;Deserialize;(System.IO.TextReader,System.Type);;Argument[0];ReturnValue;taint",
"Newtonsoft.Json;JsonSerializer;false;Serialize;(Newtonsoft.Json.JsonWriter,System.Object);;Argument[1];Argument[0];taint",
"Newtonsoft.Json;JsonSerializer;false;Serialize;(Newtonsoft.Json.JsonWriter,System.Object,System.Type);;Argument[1];Argument[0];taint",
"Newtonsoft.Json;JsonSerializer;false;Serialize;(System.IO.TextWriter,System.Object);;Argument[1];Argument[0];taint",
"Newtonsoft.Json;JsonSerializer;false;Serialize;(System.IO.TextWriter,System.Object,System.Type);;Argument[1];Argument[0];taint"
]
}
}
@@ -196,41 +223,23 @@ module JsonNET {
LinqClass() { this.getDeclaringNamespace() instanceof LinqNamespace }
}
/** The `NewtonSoft.Json.Linq.JObject` class. */
class JObjectClass extends LinqClass, LibraryTypeDataFlow {
JObjectClass() { this.hasName("JObject") }
override predicate callableFlow(
CallableFlowSource source, CallableFlowSink sink, SourceDeclarationCallable c,
boolean preservesValue
) {
// ToString method
c = this.getAMethod("ToString") and
source instanceof CallableFlowSourceQualifier and
sink instanceof CallableFlowSinkReturn and
preservesValue = false
or
// Parse method
c = this.getParseMethod() and
source = any(CallableFlowSourceArg arg | arg.getArgumentIndex() = 0) and
sink instanceof CallableFlowSinkReturn and
preservesValue = false
or
// operator string
c =
any(Operator op |
op.getDeclaringType() = this.getABaseType*() and op.getReturnType() instanceof StringType
) and
source.(CallableFlowSourceArg).getArgumentIndex() = 0 and
sink instanceof CallableFlowSinkReturn and
preservesValue = false
or
// SelectToken method
c = this.getSelectTokenMethod() and
source instanceof CallableFlowSourceQualifier and
sink instanceof CallableFlowSinkReturn and
preservesValue = false
/** Data flow for `Newtonsoft.Json.Linq.JToken`. */
private class JTokenClassFlowModelCsv extends SummaryModelCsv {
override predicate row(string row) {
row =
[
"Newtonsoft.Json.Linq;JToken;false;SelectToken;(System.String);;Argument[-1];ReturnValue;taint",
"Newtonsoft.Json.Linq;JToken;false;SelectToken;(System.String,Newtonsoft.Json.Linq.JsonSelectSettings);;Argument[-1];ReturnValue;taint",
"Newtonsoft.Json.Linq;JToken;false;SelectToken;(System.String,System.Boolean);;Argument[-1];ReturnValue;taint",
"Newtonsoft.Json.Linq;JToken;false;ToString;();;Argument[-1];ReturnValue;taint",
"Newtonsoft.Json.Linq;JToken;false;ToString;(Newtonsoft.Json.Formatting,Newtonsoft.Json.JsonConverter[]);;Argument[-1];ReturnValue;taint",
]
}
}
/** The `NewtonSoft.Json.Linq.JObject` class. */
class JObjectClass extends LinqClass {
JObjectClass() { this.hasName("JObject") }
/** Gets the `Parse` method. */
Method getParseMethod() { result = this.getAMethod("Parse") }
@@ -238,4 +247,15 @@ module JsonNET {
/** Gets the `SelectToken` method. */
Method getSelectTokenMethod() { result = this.getABaseType*().getAMethod("SelectToken") }
}
/** Data flow for `NewtonSoft.Json.Linq.JObject`. */
private class JObjectClassFlowModelCsv extends SummaryModelCsv {
override predicate row(string row) {
row =
[
"Newtonsoft.Json.Linq;JObject;false;Parse;(System.String);;Argument[0];ReturnValue;taint",
"Newtonsoft.Json.Linq;JObject;false;Parse;(System.String,Newtonsoft.Json.Linq.JsonLoadSettings);;Argument[0];ReturnValue;taint"
]
}
}
}

View File

@@ -56,7 +56,8 @@
| Newtonsoft.Json.Linq;JToken;false;SelectToken;(System.String);;Argument[-1];ReturnValue;taint |
| Newtonsoft.Json.Linq;JToken;false;SelectToken;(System.String,Newtonsoft.Json.Linq.JsonSelectSettings);;Argument[-1];ReturnValue;taint |
| Newtonsoft.Json.Linq;JToken;false;SelectToken;(System.String,System.Boolean);;Argument[-1];ReturnValue;taint |
| Newtonsoft.Json.Linq;JToken;false;explicit conversion;(Newtonsoft.Json.Linq.JToken);;Argument[0];ReturnValue;taint |
| Newtonsoft.Json.Linq;JToken;false;ToString;();;Argument[-1];ReturnValue;taint |
| Newtonsoft.Json.Linq;JToken;false;ToString;(Newtonsoft.Json.Formatting,Newtonsoft.Json.JsonConverter[]);;Argument[-1];ReturnValue;taint |
| Newtonsoft.Json;JsonConvert;false;DeserializeAnonymousType<>;(System.String,T);;Argument[0];ReturnValue;taint |
| Newtonsoft.Json;JsonConvert;false;DeserializeAnonymousType<>;(System.String,T,Newtonsoft.Json.JsonSerializerSettings);;Argument[0];ReturnValue;taint |
| Newtonsoft.Json;JsonConvert;false;DeserializeObject;(System.String);;Argument[0];ReturnValue;taint |

View File

@@ -49,7 +49,8 @@
| Newtonsoft.Json.Linq;JToken;false;SelectToken;(System.String);;Argument[-1];ReturnValue;taint |
| Newtonsoft.Json.Linq;JToken;false;SelectToken;(System.String,Newtonsoft.Json.Linq.JsonSelectSettings);;Argument[-1];ReturnValue;taint |
| Newtonsoft.Json.Linq;JToken;false;SelectToken;(System.String,System.Boolean);;Argument[-1];ReturnValue;taint |
| Newtonsoft.Json.Linq;JToken;false;explicit conversion;(Newtonsoft.Json.Linq.JToken);;Argument[0];ReturnValue;taint |
| Newtonsoft.Json.Linq;JToken;false;ToString;();;Argument[-1];ReturnValue;taint |
| Newtonsoft.Json.Linq;JToken;false;ToString;(Newtonsoft.Json.Formatting,Newtonsoft.Json.JsonConverter[]);;Argument[-1];ReturnValue;taint |
| Newtonsoft.Json;JsonConvert;false;DeserializeAnonymousType<>;(System.String,T);;Argument[0];ReturnValue;taint |
| Newtonsoft.Json;JsonConvert;false;DeserializeAnonymousType<>;(System.String,T,Newtonsoft.Json.JsonSerializerSettings);;Argument[0];ReturnValue;taint |
| Newtonsoft.Json;JsonConvert;false;DeserializeObject;(System.String);;Argument[0];ReturnValue;taint |

View File

@@ -43,6 +43,7 @@ namespace JsonTest
Sink(jobject["1"]);
Sink(jobject["1"]["2"]);
Sink((string)jobject["1"]["2"]);
Sink(jobject.ToString());
// Linq JToken tests
Sink(jobject.First((JToken i) => true));

View File

@@ -10,7 +10,8 @@
| Json.cs:16:24:16:32 | "tainted" | Json.cs:43:18:43:29 | access to indexer |
| Json.cs:16:24:16:32 | "tainted" | Json.cs:44:18:44:34 | access to indexer |
| Json.cs:16:24:16:32 | "tainted" | Json.cs:45:18:45:42 | call to operator explicit conversion |
| Json.cs:16:24:16:32 | "tainted" | Json.cs:48:18:48:50 | call to method First<JToken> |
| Json.cs:16:24:16:32 | "tainted" | Json.cs:49:18:49:46 | call to method First<JToken> |
| Json.cs:16:24:16:32 | "tainted" | Json.cs:50:18:50:51 | call to method First<JToken> |
| Json.cs:16:24:16:32 | "tainted" | Json.cs:51:18:51:61 | call to method SelectToken |
| Json.cs:16:24:16:32 | "tainted" | Json.cs:46:18:46:35 | call to method ToString |
| Json.cs:16:24:16:32 | "tainted" | Json.cs:49:18:49:50 | call to method First<JToken> |
| Json.cs:16:24:16:32 | "tainted" | Json.cs:50:18:50:46 | call to method First<JToken> |
| Json.cs:16:24:16:32 | "tainted" | Json.cs:51:18:51:51 | call to method First<JToken> |
| Json.cs:16:24:16:32 | "tainted" | Json.cs:52:18:52:61 | call to method SelectToken |