Problem Framing
Deserialization vulnerabilities represent a critical class of security weaknesses where an application processes serialized data without adequate validation or sanitization. This allows an attacker to inject crafted serialized objects, which, when deserialized, can lead to the execution of arbitrary code, data tampering, denial-of-service, or privilege escalation [1][2][3][4]. The OWASP Top Ten has consistently listed insecure deserialization as a significant risk, highlighting its potential for severe impact [5][4]. Unlike many other vulnerabilities, deserialization flaws often leverage existing application code and libraries (gadgets) to achieve malicious objectives, making them particularly potent and challenging to eradicate by simply removing specific "dangerous" classes [6][7][8][4]. This reliance on existing code allows attackers to construct sophisticated "gadget chains" that manipulate program flow during the deserialization process, ultimately leading to control over the target system [9][10].
The core of the problem lies in the trust placed upon serialized data. Applications often serialize objects to persist state, transmit data across networks, or facilitate inter-process communication. When this serialized data originates from or can be influenced by an untrusted source, and the deserialization process lacks robust validation, a pathway for exploitation emerges [1][2][3][4]. The deserialization mechanism itself, designed to reconstruct objects, can inadvertently execute attacker-controlled code during this reconstruction phase, often before application-level validation can occur [8][4]. This makes it difficult to mitigate by simply filtering at the application layer, as the danger is inherent in the deserialization process itself.
Core Mechanics
At its heart, deserialization is the process of converting a sequence of bytes or a structured text format back into an object in memory [11][12]. This process is native to many programming languages and libraries, including Java's ObjectInputStream.readObject() [10][13][3], Python's pickle.loads() [14][15][16], PHP's unserialize() [17][18][19][20][21], Ruby's Marshal.load() [22][23][24][25][26][9], and .NET's various serializers like BinaryFormatter [27][28][29][30][31].
When an application uses these deserialization functions with untrusted input, an attacker can craft a payload that, when processed, triggers a chain of method calls on existing classes within the application's classpath. These classes and their methods, often referred to as "gadgets," are legitimate code fragments that perform specific operations. When chained together through controlled object state during deserialization, they can achieve a malicious outcome, such as executing operating system commands [7][10][32][13].
The fundamental vulnerability arises from how deserialization functions, like Java's ObjectInputStream.readObject(), can invoke custom readObject(), writeObject(), finalize(), or other special "magic" methods within objects during the deserialization process [10][13]. Similarly, Python's pickle uses the __reduce__ method to execute arbitrary code [14][15][16], and PHP's unserialize() can trigger magic methods like __destruct() or __wakeup() [18][20][21][33]. Ruby's Marshal.load can initiate code execution through a series of method calls on deserialized objects, often involving classes from the standard library or gems [22][23][24][26][9].
Gadget chains exploit this by chaining together these methods, where the output of one method call becomes the input for another, ultimately leading to a "sink" method that performs a dangerous operation like Runtime.exec() or System.arraycopy() [6][10][13][8]. The availability and nature of these gadgets depend heavily on the language, the libraries available on the classpath, and the specific deserialization format used [32][13]. Tools like ysoserial for Java [32] and ysoserial.net for .NET [29] are designed to generate payloads based on known gadget chains.
Notable Techniques
The exploitation of deserialization vulnerabilities often revolves around identifying and chaining available gadgets. The techniques vary significantly based on the programming language and the specific serialization format.
Java Deserialization
Java deserialization has a long history of exploitation, primarily leveraging the java.io.Serializable interface and the ObjectInputStream.readObject() method. Gadget chains often utilize classes from common libraries like Apache Commons Collections, Spring Framework, and Groovy [10][32][13][34][3][4].
- Commons Collections Gadget Chains: One of the earliest and most well-known chains involves
invokerTransformerandChainedTransformerwithinLazyMapto execute arbitrary code [10][32][35][34][4]. TheTemplatesImplgadget, found incom.sun.org.apache.xalan.internal.xsltc.trax, allows for bytecode execution by manipulatingtransletBytecodes[36][37][32]. - Spring Framework Gadgets: Gadgets within the Spring framework can leverage classes like
FileSystemXmlApplicationContextto load remote XML configurations, orJndiTemplateto facilitate JNDI lookups, potentially leading to Remote Class Loading or RCE [32][38][34]. - JNDI Injection: Exploiting JNDI (Java Naming and Directory Interface) through deserialization is a powerful technique. By controlling where JNDI performs lookups, attackers can force the application to connect to attacker-controlled LDAP or RMI servers, leading to RCE [39][38][34].
- XMLDecoder: Java's
XMLDecodercan be vulnerable when parsing untrusted XML, allowing for arbitrary object creation and method invocation [39][3][4]. - XStream: The XStream library, especially older versions, is susceptible to deserialization attacks when parsing untrusted XML input [40][41][6][39]. The Apache Struts REST plugin's use of XStream was a notable vector [40][41].
- SnakeYAML: This library, used for YAML parsing, can lead to RCE if
yaml.loadis used with untrusted input without theSafeLoader[42][43][39].
Python Deserialization
Python's pickle module is notoriously insecure, as its documentation explicitly warns against unpickling untrusted data [14][15][8][12][16][4].
__reduce__Method: The core ofpickleexploitation lies in the__reduce__method, which can return a callable and its arguments, allowing for arbitrary code execution during deserialization [14][15][8][16][4]. Tools likepickleballaim to mitigate this by analyzing and creating safe loading policies [44].- PyYAML: Similar to Java, Python's
yaml.load(withoutSafeLoader) can be exploited to instantiate arbitrary Python objects, leading to RCE [14][43][45][12][46]. - JSONpickle: This library, used for serializing Python objects to JSON, can also be vulnerable if not handled carefully [14][45].
- ML Model Loading: The widespread use of
picklefor saving ML models in frameworks like PyTorch has created a significant attack surface for supply chain poisoning [47][48][49][16]. Vulnerabilities in scanning tools likepickleScanhave been discovered, highlighting the difficulty in detecting malicious models [48][50][49].
PHP Deserialization
PHP's unserialize() function is the primary vector for object injection vulnerabilities.
- Magic Methods: Exploitation often targets magic methods like
__destruct()and__wakeup(), which are automatically called during deserialization or object destruction, enabling execution of attacker-controlled code [17][18][19][20][21][33][4]. - POP Chains: Property-Oriented Programming (POP) chains in PHP involve manipulating object properties to hijack control flow, ultimately leading to code execution [51][19][52].
- PHAR Deserialization: The
phar://stream wrapper in PHP can automatically deserialize PHAR archive metadata, enabling RCE through manipulated metadata objects [51][19][33].
Ruby Deserialization
Ruby's Marshal module and YAML.load are common targets for deserialization attacks.
Marshal.loadExploitation: Gadget chains have been developed for Ruby'sMarshalmodule, often leveraging classes from the standard library andrubygemsto achieve RCE [22][23][24][26][9]. These chains have evolved over time as Ruby versions andrubygemshave been patched [22][24].YAML.loadExploitation: Unsafe deserialization of YAML data is also a significant risk in Ruby, particularly when user input is passed toYAML.loadwithout proper sanitization [23][24][9].
.NET Deserialization
.NET applications present various deserialization vulnerabilities, often involving the BinaryFormatter and ViewState.
BinaryFormatter: This formatter is inherently insecure and widely used, allowing for RCE when deserializing untrusted input [27][28][29][30][31][53].ysoserial.netis a key tool for generating .NET deserialization payloads [29].ViewState: ASP.NET'sViewStatemechanism, particularly when machine keys are compromised or validation is absent, can be exploited for deserialization attacks, as seen in SharePoint vulnerabilities [28][54][55][30].ObjectDataProviderandXmlSerializer: Gadgets likeObjectDataProviderwithinXmlSerializerorDataContractSerializerleverage .NET's reflection capabilities to execute arbitrary code [27][56][29].Json.NET(Newtonsoft.Json): WhenTypeNameHandlingis enabled,Json.NETcan be vulnerable to RCE by allowing the specification of arbitrary .NET classes during deserialization [57].
Detection and Prevention
The overarching principle for preventing deserialization vulnerabilities is to never deserialize untrusted data. If deserialization of untrusted data is unavoidable, robust validation, integrity checks, and strict type constraints are essential [2][45][3][4].
Detection Strategies
- Code Review (White-box): Scrutinize code for deserialization functions (
pickle.loads,unserialize,Marshal.load,ObjectInputStream.readObject,Convert.Deserialize, etc.) and analyze the origin of the data being deserialized. Look for patterns where user input directly feeds into these functions without validation [45][8][33][4]. Static Application Security Testing (SAST) tools can help identify these patterns [5][8]. - Network Traffic Analysis (Black-box): Identify serialized data formats in HTTP requests (e.g., Base64 encoded strings, specific magic bytes like
AC ED 00 05for Java,rO0for Base64-encoded Java, orO:for PHP) [45][58][34][33][12]. Tools like Burp Suite can aid in flagging potential serialized objects [33]. - Runtime Monitoring: Monitor for deserialization exceptions, unusual memory/CPU consumption during deserialization operations, or unexpected process spawning that might indicate exploitation [5][59][53]. Endpoint Detection and Response (EDR) solutions can detect post-exploitation activities [59][53].
- Dependency Scanning: Regularly scan dependencies for known deserialization vulnerabilities. Libraries and frameworks often introduce vulnerabilities through their transitive dependencies (shadow vulnerabilities) [43].
Prevention and Mitigation
- Avoid Deserializing Untrusted Data: This is the most effective mitigation. Where possible, use data interchange formats like JSON, XML, or Protobuf that do not reconstruct arbitrary objects [5][2][18][45][8][3][4].
- Input Validation and Sanitization: If deserialization is necessary, rigorously validate and sanitize input data before processing. This includes checking data types, lengths, and formats. However, comprehensive validation is challenging, as the attack surface is vast [2][45][4].
- Integrity Checks: Implement digital signatures or HMACs to verify the integrity and authenticity of serialized data before deserialization. This ensures that the data has not been tampered with [5][2][45][8][3].
- Serialization Filters (Java): For Java, utilize serialization filters (JEP 290 and later) to create an allowlist of classes that are permitted to be deserialized [45][39][59][8]. This is a more granular and secure approach than simple blocklisting.
- Use Safer Serialization Libraries/Formats: Opt for libraries or formats that are designed with security in mind and do not allow arbitrary code execution, such as
Safetensorsfor ML models [48][44][49]. - Principle of Least Privilege: Run deserialization code in low-privilege environments or sandboxed containers to limit the impact of a successful exploit [5][3].
- Keep Libraries Updated: Regularly update all libraries and frameworks to patch known deserialization vulnerabilities [2][13][3].
- Disable Dangerous Serializers: Avoid known insecure serializers like .NET's
BinaryFormatter[30][31].
Tooling
A variety of tools assist in the discovery, generation, and analysis of deserialization exploits and vulnerabilities.
ysoserial(Java): A widely used tool for generating Java deserialization payloads, containing numerous gadget chains for various libraries [32][60][39][34].ysoserial.net(.NET): The .NET equivalent ofysoserial, providing payload generation for .NET deserialization vulnerabilities [29][30][61].Burp SuiteExtensions: Plugins for Burp Suite, such asSuperSerial,burp-ysoserial, andJava Deserialization Scanner, can automate the detection and exploitation of deserialization flaws [60][39][34][33].marshalsec: A Java unmarshalling security tool that aids in turning data into code execution, including JNDI and RMI exploitation [39][34].jdeserialize: A utility for converting serialized Java objects into a human-readable format, aiding in manual analysis [60].PHPGGC: A tool for generating PHP deserialization payloads based on various frameworks [19].r2pickledec: A Radare2 plugin for decompiling and analyzing Python pickle files [16].PickleScan: A tool designed to scan Python pickle files for malicious content, though it has been found to have bypassable vulnerabilities [48][50][49].HeySerial.pyandCheckYoself.py: Tools developed by Mandiant for generating hunting rules and validating deserialization exploits [61].Web Security Academy Labs: PortSwigger provides a range of interactive labs for practicing the exploitation of deserialization vulnerabilities across PHP, Ruby, and Java [33][4].
Recent Developments
The landscape of deserialization vulnerabilities continues to evolve, with new chains and exploitation techniques being discovered regularly. Recent research highlights the persistent threat of these vulnerabilities across various languages and frameworks.
- Ruby
Marshal.loadChains: New universal RCE gadget chains for Ruby have been discovered, targeting recent versions of Ruby and demonstrating the ongoing cat-and-mouse game between attackers and defenders [22][24]. - .NET
ViewStateandBinaryFormatter: Exploitation of .NETViewStatein products like SharePoint [54][55][30] and the continued dangers ofBinaryFormatterremain significant concerns [30][31][53]. - Python
picklein ML Pipelines: The use ofpicklefor ML model serialization has become a major vector for supply chain attacks, with researchers uncovering numerous ways to bypass security scanners likepickleScan[47][48][50][49]. - JavaScript/TypeScript: The React Server Components "Flight" protocol has been found to have critical deserialization vulnerabilities allowing RCE [62].
- YAML Deserialization: Vulnerabilities in libraries like PyYAML continue to surface, often as transitive dependencies, leading to RCE in various applications [43][39].
- Automated Gadget Discovery: Research is advancing the automation of finding gadget chains through techniques like deserialization-guided call graph construction [63][64][38].
Where to Go Deeper
To further your understanding and hone your skills in combating deserialization vulnerabilities, explore the following resources:
- OWASP Top Ten: Familiarize yourself with the OWASP Top Ten list, particularly the "Insecure Deserialization" category, to grasp its historical and ongoing significance [5][58][8][3].
ysoserialProject: Study theysoserial(Java) andysoserial.net(.NET) projects on GitHub. Analyzing their payloads and supported gadgets provides deep insights into common exploitation techniques [32][29].- PortSwigger Web Security Academy: The Web Security Academy offers comprehensive learning materials and hands-on labs specifically dedicated to insecure deserialization across multiple languages [33][4].
- Academic Research Papers: Explore papers from security conferences like USENIX Security and ACM, which often detail novel deserialization attack vectors, gadget discovery techniques, and mitigation strategies [63][65][66][38].
- Security Blogs and Write-ups: Many security researchers and companies publish detailed analyses of deserialization vulnerabilities, including specific CVEs, exploitation techniques, and proof-of-concept code. Following blogs from organizations like Trail of Bits, Bishop Fox, SentinelOne, Mandiant, and others will provide current threat intelligence and practical examples [22][67][68][69][36][40][51][28][54][55][43][48][23][70][24][71][30][57][72][59][53][73][61][16].
- PayloadsAllTheThings: This GitHub repository is an invaluable resource for finding serialization payloads and examples across various languages [27][14][23][19][30][39][34].