rspec/rules/S5773/csharp/rule.adoc
Fred Tingaud 16f6c0aecf
Inline adoc when include has no additional value (#1940)
Inline adoc files when they are included exactly once.

Also fix language tags because this inlining gives us better information
on what language the code is written in.
2023-05-25 14:18:12 +02:00

125 lines
6.5 KiB
Plaintext

== Why is this an issue?
:link-with-uscores1: https://docs.microsoft.com/en-us/dotnet/api/system.codedom.compiler.tempfilecollection.-ctor?view=netframework-4.8#System_CodeDom_Compiler_TempFileCollection__ctor
During the deserialization process, the state of an object will be reconstructed from the serialized data stream which can contain dangerous operations.
For example, a well-known attack vector consists in serializing an object of type ``{link-with-uscores1}[TempFileCollection]`` with arbitrary files (defined by an attacker) which will be deleted on the application deserializing this object (when the https://docs.microsoft.com/en-us/dotnet/api/system.codedom.compiler.tempfilecollection.finalize?view=netframework-4.8[finalize() ]method of the TempFileCollection object is called). This kind of types are called "https://github.com/pwntester/ysoserial.net[gadgets]".
Instead of using ``++BinaryFormatter++`` and similar serializers, it is recommended to use safer alternatives in most of the cases, such as https://docs.microsoft.com/en-us/dotnet/api/system.xml.serialization.xmlserializer?view=net-5.0[XmlSerializer] or https://docs.microsoft.com/en-us/dotnet/api/system.runtime.serialization.datacontractserializer?view=net-5.0[DataContractSerializer]. If it's not possible then try to mitigate the risk by restricting the types allowed to be deserialized:
* by implementing an "allow-list" of types, but keep in mind that novel dangerous types are regularly discovered and this protection could be insufficient over time.
* or/and implementing a tamper protection, such as https://en.wikipedia.org/wiki/HMAC[message authentication codes] (MAC). This way only objects serialized with the correct MAC hash will be deserialized.
=== Noncompliant code example
For https://docs.microsoft.com/en-us/dotnet/api/system.runtime.serialization.formatters.binary.binaryformatter?view=netframework-4.8[BinaryFormatter], https://docs.microsoft.com/en-us/dotnet/api/system.runtime.serialization.netdatacontractserializer?view=netframework-4.8[NetDataContractSerializer], https://docs.microsoft.com/en-us/dotnet/api/system.runtime.serialization.formatters.soap.soapformatter?view=netframework-4.8[SoapFormatter] serializers:
[source,csharp]
----
var myBinaryFormatter = new BinaryFormatter();
myBinaryFormatter.Deserialize(stream); // Noncompliant: a binder is not used to limit types during deserialization
----
https://docs.microsoft.com/en-us/dotnet/api/system.web.script.serialization.javascriptserializer?view=netframework-4.8[JavaScriptSerializer] should not use SimpleTypeResolver or other weak resolvers:
[source,csharp]
----
JavaScriptSerializer serializer1 = new JavaScriptSerializer(new SimpleTypeResolver()); // Noncompliant: SimpleTypeResolver is unsecure (every types is resolved)
serializer1.Deserialize<ExpectedType>(json);
----
https://docs.microsoft.com/en-us/dotnet/api/system.web.ui.losformatter?view=netframework-4.8[LosFormatter] should not be used without MAC verification:
[source,csharp]
----
LosFormatter formatter = new LosFormatter(); // Noncompliant
formatter.Deserialize(fs);
----
=== Compliant solution
https://docs.microsoft.com/en-us/dotnet/api/system.runtime.serialization.formatters.binary.binaryformatter?view=netframework-4.8[BinaryFormatter], https://docs.microsoft.com/en-us/dotnet/api/system.runtime.serialization.netdatacontractserializer?view=netframework-4.8[NetDataContractSerializer ], https://docs.microsoft.com/en-us/dotnet/api/system.runtime.serialization.formatters.soap.soapformatter?view=netframework-4.8[SoapFormatter] serializers should use a binder implementing a whitelist approach to limit types during deserialization (at least one exception should be thrown or a null value returned):
[source,csharp]
----
sealed class CustomBinder : SerializationBinder
{
public override Type BindToType(string assemblyName, string typeName)
{
if (!(typeName == "type1" || typeName == "type2" || typeName == "type3"))
{
throw new SerializationException("Only type1, type2 and type3 are allowed"); // Compliant
}
return Assembly.Load(assemblyName).GetType(typeName);
}
}
var myBinaryFormatter = new BinaryFormatter();
myBinaryFormatter.Binder = new CustomBinder();
myBinaryFormatter.Deserialize(stream);
----
https://docs.microsoft.com/en-us/dotnet/api/system.web.script.serialization.javascriptserializer?view=netframework-4.8[JavaScriptSerializer] should use a resolver implementing a whitelist to limit types during deserialization (at least one exception should be thrown or a null value returned):
[source,csharp]
----
public class CustomSafeTypeResolver : JavaScriptTypeResolver
{
public override Type ResolveType(string id)
{
if(id != "ExpectedType") {
throw new ArgumentNullException("Only ExpectedType is allowed during deserialization"); // Compliant
}
return Type.GetType(id);
}
}
JavaScriptSerializer serializer = new JavaScriptSerializer(new CustomSafeTypeResolver()); // Compliant
serializer.Deserialize<ExpectedType>(json);
----
https://docs.microsoft.com/en-us/dotnet/api/system.web.ui.losformatter?view=netframework-4.8[LosFormatter] serializer with MAC verification:
[source,csharp]
----
LosFormatter formatter = new LosFormatter(true, secret); // Compliant
formatter.Deserialize(fs);
----
== Resources
* https://owasp.org/Top10/A08_2021-Software_and_Data_Integrity_Failures/[OWASP Top 10 2021 Category A8] - Software and Data Integrity Failures
* https://docs.microsoft.com/en-us/dotnet/standard/serialization/binaryformatter-security-guide?s=03[docs.microsoft.com] - BinaryFormatter security guide
* https://owasp.org/www-project-top-ten/2017/A8_2017-Insecure_Deserialization[OWASP Top 10 2017 Category A8] - Insecure Deserialization
* https://cwe.mitre.org/data/definitions/134[MITRE, CWE-134] - Use of Externally-Controlled Format String
* https://cwe.mitre.org/data/definitions/502[MITRE, CWE-502] - Deserialization of Untrusted Data
* https://www.sans.org/top25-software-errors/#cat2[SANS Top 25] - Risky Resource Management
* https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/Deserialization_Cheat_Sheet.md[OWASP Deserialization Cheat Sheet]
ifdef::env-github,rspecator-view[]
'''
== Implementation Specification
(visible only on this page)
include::../message.adoc[]
=== Highlighting
Primary: See the code examples
Secondary:
* When a `JavaScriptTypeResolver` is used, on the `ResolveType` method
* message: "This method allows all types."
'''
== Comments And Links
(visible only on this page)
include::../comments-and-links.adoc[]
endif::env-github,rspecator-view[]