Deserialization
Unsafe Deserialization (also referred to as Insecure Deserialization) is a vulnerability wherein malformed and untrusted data input is insecurely deserialized by an application. It is exploited to hijack the logic flow of the application end might result in the execution of arbitrary coden. Although this is 't exactly a simple attack to employ, it featured inOWASP's Top 10most recent iteration as part of the Software and Data Integrity Failures risk, due to the severity of impact upon compromise.
The process of converting an object state or data structure into a storable or transmissible format is called serialization. Deserialization is its opposite — the process of extracting the serialized data to reconstruct the original object version
Unsafe Deserialization issues arise when an attacker is able to pass ad hoc malicious data into user-supplied data to be deserialized. This could result in arbitrary object injection into the application that might influence the correct target behavior.
Impact
A successful Unsafe Deserialization attack can result in the full compromise of the confidentiality, integrity, and availability of the target system, and the oft-cited Equifax breach is probably the best example of the worst outcome that can arise. In Equifax's case, an unsafe Java deserialization attack leveraging the Struts 2 framework resulted in remote code execution, which, in turn, led to the largest data breach in history.
Prevention
It is important to consider any development project from an architectural standpoint to determine when and where serialization is necessary. If it is unnecessary, consider using a simpler format when passing data.
In cases where it is impossible to forego serialization without disrupting the application's operational integrity, developers can implement a range of defense-in-depth measures to mitigate the chances of being exploited.
- Use serialization that only permits primitive data types.
- Use a serialization library that provides cryptographic signature and encryption features to ensure serialized data are obtained untainted.
- Authenticate before deserializing.
- Use low privilege environments to isolate and run code that deserializes.
Finally, if possible, replace object serialization with data-only serialization formats, such as JSON.
testing
Verify that serialization is not used when communicating with untrusted clients. If this is not possible, ensure that adequate integrity controls (and possibly encryption if sensitive data is sent) are enforced to prevent deserialization attacks including object injection.
OWASP ASVS:1.5.2, 5.5.1, 5.5.3
Types of Deserializations
Unsafe Deserialization in .NET
Vulnerable Example
The .NET framework offers several instances of deserialization. Developers will likely be familiar with the following example, where some untrusted binary data is deserialized to create some objects:
[Serializable]
public class SomeClass
{
public string SomeProperty { get; set; }
public double SomeOtherProperty { get; set; }
}
class Program
{
static void Main(string[] args)
{
BinaryFormatter binaryFormatter = new BinaryFormatter();
MemoryStream memoryStream = new MemoryStream(File.ReadAllBytes("untrusted.file"));
SomeClass obj = (SomeClass)binaryFormatter.Deserialize(memoryStream);
Console.WriteLine(obj.SomeProperty);
Console.WriteLine(obj.SomeOtherProperty);
}
}
The above program merrily deserializes not only instances of SomeClass (even though a class cast error is raised for other objects), but also might be enough to trigger dangerous behaviors. For example, a malicious user could leverage publicly available tools such asysoserial.net to easily craft payloads that exploit the presence of external libraries, and thus build a chain of gadgets that eventually lead to RCE.
Alternatively, an attacker with knowledge of the source code of the application could attempt to locate dangerous classes in the code base. For example, suppose that somewhere in the application, the following class is defined:
[Serializable]
public class DangerousClass