All rules
CA2322Security Enabled by default: No
Ensure JavaScriptSerializer is not initialized with SimpleTypeResolver before deserializing
Ensure JavaScriptSerializer is not initialized with SimpleTypeResolver before deserializing
Microsoft docsDescription
This rule finds System.Web.Script.Serialization.JavaScriptSerializer deserialization method calls or references, when the System.Web.Script.Serialization.JavaScriptSerializer may have been initialized with a System.Web.Script.Serialization.SimpleTypeResolver.
Cause
A System.Web.Script.Serialization.JavaScriptSerializer deserialization method was called or referenced and the System.Web.Script.Serialization.JavaScriptSerializer may have been initialized with a System.Web.Script.Serialization.SimpleTypeResolver.
By default, this rule analyzes the entire codebase, but this is configurable.
How to fix violations
- Ensure System.Web.Script.Serialization.JavaScriptTypeResolver objects aren't initialized with a System.Web.Script.Serialization.SimpleTypeResolver.
- If your code needs to read data serialized using a System.Web.Script.Serialization.SimpleTypeResolver, restrict deserialized types to an expected list by implementing a custom System.Web.Script.Serialization.JavaScriptTypeResolver.
- Make the serialized data tamper-proof. After serialization, cryptographically sign the serialized data. Before deserialization, validate the cryptographic signature. Protect the cryptographic key from being disclosed and design for key rotations.
Example
using System.Web.Script.Serialization;
public class ExampleClass
{
public JavaScriptSerializer Serializer { get; set; }
public T Deserialize<T>(string str)
{
return this.Serializer.Deserialize<T>(str);
}
}
using System.Web.Script.Serialization;
public class ExampleClass
{
public T Deserialize<T>(string str)
{
JavaScriptSerializer s = new JavaScriptSerializer();
return s.Deserialize<T>(str);
}
}
using System.Web.Script.Serialization;
public class BookRecord
{
public string Title { get; set; }
public string Author { get; set; }
public int PageCount { get; set; }
public AisleLocation Location { get; set; }
}
public class AisleLocation
{
public char Aisle { get; set; }
public byte Shelf { get; set; }
}
public class ExampleClass
{
public JavaScriptSerializer Serializer { get; set; }
public BookRecord DeserializeBookRecord(string s)
{
return this.Serializer.Deserialize<BookRecord>(s);
}
}
using System;
using System.Web.Script.Serialization;
public class BookRecordTypeResolver : JavaScriptTypeResolver
{
// For compatibility with data serialized with a JavaScriptSerializer initialized with SimpleTypeResolver.
private static readonly SimpleTypeResolver Simple = new SimpleTypeResolver();
public override Type ResolveType(string id)
{
// One way to discover expected types is through testing deserialization
// of **valid** data and logging the types used.
////Console.WriteLine($"ResolveType('{id}')");
if (id == typeof(BookRecord).AssemblyQualifiedName || id == typeof(AisleLocation).AssemblyQualifiedName)
{
return Simple.ResolveType(id);
}
else
{
throw new ArgumentException("Unexpected type ID", nameof(id));
}
}
public override string ResolveTypeId(Type type)
{
return Simple.ResolveTypeId(type);
}
}
public class BookRecord
{
public string Title { get; set; }
public string Author { get; set; }
public int PageCount { get; set; }
public AisleLocation Location { get; set; }
}
public class AisleLocation
{
public char Aisle { get; set; }
public byte Shelf { get; set; }
}
public class ExampleClass
{
public BookRecord DeserializeBookRecord(string s)
{
JavaScriptSerializer serializer = new JavaScriptSerializer(new BookRecordTypeResolver());
return serializer.Deserialize<BookRecord>(s);
}
}Your vote
Group results
0 yes 0 no
ConsensusNone (disabled)
Severity preference (yes voters)
Suggestion0
Warning0
Error0