Last updated
Last updated
An example codebase along with it's CodeQL code will be added to the repository soon.
Newtonsoft.Json
PackageAn example of vulnerable .NET code that uses the Newtonsoft.Json package and is vulnerable to JSON deserialization attacks:
This code deserializes JSON data into a Person
object using the JsonConvert.DeserializeObject
method provided by the Newtonsoft.Json package. The $type
field in the JSON data is used to specify the type of object to deserialize, allowing an attacker to potentially execute arbitrary code during the deserialization process.
To identify such code patterns, look for the use of the JsonConvert.DeserializeObject
method (or other similar methods) with user-controlled input data, especially if the $type
field is being used to specify the object type to deserialize. Additionally, check if any of the types being deserialized are sensitive or could potentially execute malicious code. It's important to always validate user input data before passing it to a deserialization method to prevent JSON deserialization attacks.
In this code, the type of object to deserialize is defined using a string that specifies the fully-qualified name of the object type ("JsonDeserializationExample.Person, JsonDeserializationExample"
). However, there is no input validation being done on this string, so an attacker could potentially supply a different type name and execute arbitrary code during the deserialization process.
To prevent JSON deserialization attacks, it's important to validate user input data before passing it to any deserialization method, and to avoid using user input to define the type of object to deserialize. Instead, use a fixed set of known types or create a custom JsonConverter
to handle deserialization of specific types.
An example of a more secure version of the .NET code using the Newtonsoft.Json package, with input validation and a fixed set of known types:
In this code, the JsonConvert.DeserializeObject
method is called with the Person
class as the generic parameter, so the type of object to deserialize is explicitly set and does not rely on user input. Additionally, the input JSON data is not trusted and is validated against the expected schema defined by the Person
class.
This approach is more secure than the previous example because it avoids using user input to define the type of object to deserialize and validates input data before passing it to the deserialization method.
The TypeNameHandling
property in Newtonsoft.Json is used to specify how type names should be handled during serialization and deserialization. The TypeNameHandling
enumeration has four possible values:
None
(0): No type name handling is performed.
Objects
(1): Only object types are given a type name.
Arrays
(2): Only array types are given a type name.
All
(3): Both object and array types are given a type name.
References: