The serialization and deserialization processes make it easier for applications to communicate by preserving an object’s attributes and assigned values. While serialization breaks the object into smaller components, deserialization rebuilds it so that the application can interact with it. Unfortunately, as soon as any code is broken into smaller chunks, attackers can find a way to insert malicious code into the process, undermining the application’s security.
To mitigate risks arising from insecure deserialization, developers should understand what it is, the risks it poses, and how to mitigate them.
What is serialization?
The serialization process converts unordered, complex object states, like values or data, into a byte stream for:
- transportation, like communication between applications,
- persistence, like in a database
The process saves the object’s state to be recreated later.
Some examples of serialization technologies include:
- XML and SOAP serialization: Converting an object’s public fields and properties into an XML stream that can conform to SOAP specifications
- Binary serialization: Converting an object’s public and private fields and class names into a byte stream
What is deserialization?
The deserialization process extracts data from files, networks, or byte streams, rebuilding it into objects. In distributed systems, the serialization and deserialization processes enable object sharing across separate nodes, like between applications or through firewalls. Instead of writing code that handles the delivery of each object component, developers can save, transmit, and recreate objects in a standardized way.
What is insecure deserialization?
Insecure deserialization means that threat actors can use the deserialization mechanism to insert untrusted data into the process, enabling them to manipulate serialized objects and pass malicious code or objects to the application. Vulnerabilities typically reside in the deserialization logic, allowing attackers to modify object attributes or insert new ones via:
- Application logic
- Magic events, where the programming language gets called automatically
- Object insertion
Types of deserialization attacks
The primary deserialization attack types are:
- Blind deserialization: allows for remote code execution (RCE) on target server protected by security controls, like firewalls
- Asynchronous (stored) deserialization: stores malicious serialized data on target server database so application deserialization triggers the malicious code
- Deferred-execution deserialization: bypasses non-executable functions and executes in application after deserialization, allowing for RCE
Impact of deserialization vulnerabilities
When attackers exploit deserialization vulnerabilities, they seek to engage in RCE attacks that can lead to:
- Initial access: Gaining an initial foothold through a public-facing application that enables them to run commands on the underlying machine
- Information disclosure: Installing data-exfiltration malware or executing commands to extract and exfiltrate data from the device
- Denial of Service (DoS): Running malicious code on the application’s host server to disrupt operations
- Cryptomining: Deploying and executing malicious code that uses computing resources to mine cryptocurrency
- Ransomware: Deploying and installing ransomware through an application installed on a vulnerable device
Mitigating Deserialization Vulnerability Risks
At the source code level, deserialization attacks are often programming-language related.The Open Worldwide Application Security Project (OWASP) offers various risk mitigation strategies that are specific to programming language and language-agnostic.
Mitigations by Language
To mitigate risks, developers should be able to identify different data that can’t be trusted during deserialization.
For this language, structural testing should include reviewing or:
- Use of unserialize() unction
- How the application accept external parameters
For this language, developers should:
- Review for traffic data containing the symbol dot at the end
- Engage in structural testing for code containing
- pickle/c_pickle/pickle with load/loads
- PyYAML with load
- Jsonpickle with encode or store
Java may be the programming language most likely to have a deserialization vulnerability. Some mitigation strategies include:
- Preventing arbitrary classes from being deserialized
- Checking input length and number of objects deserialized
- Structural testing of the Java API for:
- XMLdecoder with external user-defined parameters
- XStream with fromXML
- ObjectInputStream with readObject
- readObject, readObectNoData, readReslve, readExtenral
- Data traffic patterns suggesting data was sent in Java serialization streams
- Preventing sensitive information from end-user control or user exposure during serialization with the keyword transient
- Preventing deserialization of domain objects with a “readObject()” method and “final” modifier
- Hardening java.io.ObjectInputStream
Some mitigation strategies for this language include:
- Searching base64 encoded content for anything starting with AAEAAAD/////
- Searching for content containing TypeObject or $type:
Additionally, Microsoft warns against using the BinaryFormatter since it poses security risks.
Use Alternative Data Formats
Using formats like JSON or XML reduces the security issues associated with custom deserialization logic.
Requiring an authenticated signature helps validate the messages before the application processes them, mitigating risks arising from malicious user-controlled inputs.
Implement Detection and Mitigation Tools and Processes
When possible, developers should use automated scanning tools to identify deserialization risks across their source code, including identifying and monitoring:
- Third-party components
- Dependencies across components
Additionally, penetration testing can identify vulnerabilities arising from business logic errors that create deserialization vulnerabilities embedded in the application.
Qwiet AI: Visibility into Deserialization Vulnerabilities
With Qwiet AI’s preZero platform, you can check for vulnerabilities in millions of lines of code in minutes, enabling you to get the accurate and detailed findings necessary to protect your application from insecure deserialization.
PreZero identifies vulnerabilities and then adds context to help you prioritize remediation activities by giving you visibility into the ones attackers can actually exploit. Using Qwiet AI, you can eliminate thousands of false positives for a noise-free list that prioritizes your riskiest code, enabling faster time-to-market.
Take our preZero platform for a free spin to see how Qwiet AI can help you identify and remediate race condition vulnerabilities.