In starting to prepare for the Offensive Security Advanced Web Application Exploitation (AWAE) course, I ran across a vulnerability category that I was certainly familiar with but hadn’t run across in the wild lately. Insecure deserialization is an interesting category of vulnerabilities, as it’s part of the OWASP Top 10 but usually isn’t the first type of vulnerability that’s going to come to your mind. That’s probably because these weaknesses are fairly specific in the types of applications and conditions required in order to be exploitable. But there place in the OWASP Top 10 is likely also driven by their impact, as opposed to their likelihood, as insecure deserialization issues often result in remote code execution (RCE).
What is Insecure Deserialization?
An application is vulnerable to insecure deserialization if they accept untrusted user input in the form of a serialized object and then deserialize it in an unsafe way. Most commonly, this type of functionality is observed in PHP applications, Java applications, or .NET applications, but any language that has serialization capabilities can be affected. There’s nothing wrong with serialized objects inherently, as it’s just a way to more efficiently store or transmit data over a network. The issues come in when a manipulated, serialized object can be used to affect the data contained in an object or the application flow in a malicious way.
Identifying These Vulnerabilities
It can be tough to identify insecure deserialization weaknesses in applications. From a black box perspective, it may be almost impossible if you can’t get any information from errors or through stack traces. During a penetration test, it may be possible to identify serialized data (e.g. “rO0” in Base-64 indicates a Java serialized object) and there are scanners that look for these issues, but exploitation rarely works out of the box and requires a significant amount of customization, trial, and error.
With white box testing, however, deserialization-related vulnerabilities can be more easily identified. By looking for certain key functions or chains of functions, it may be possible to directly identify a potential weakness and understand how it could be exploited. But even then, a high-level of technical knowledge and the ability to craft custom exploits would be required in most cases. There are some deserialization libraries that are vulnerable to out-of-the-box exploits where people have written proof-of-concept code, but most of the time these issues can be avoided by using the most recent versions of these libraries or alternative options.
Preventing Insecure Deserialization
As with most issues, there’s not really a silver bullet here but there are a lot of things to consider when trying avoid falling victim to these issues. Probably most importantly, you can immediately reduce your risk by avoiding native serialization functions altogether and opting to use JSON or XML. While you can still make a mistake and create an issue when using a “pure-data” object format, it’s significantly less likely.
If that’s not an option, make sure you are using a serialization library that doesn’t have any known vulnerabilities associated with it. Then, use input validation to check/test the validity of untrusted input provided as part of an object prior to processing it. To add some assurance here, you could also sign serialized objects and check the authenticity of the signature prior to processing to ensure it hadn’t been tampered with. There are also language-specific libraries that can be bolted on to help prevent these attacks from being exploitable, such as NotSoSerial for Java.
Ultimately, this just scratches the surface of deserialization vulnerabilities. This is a pretty complex category of vulnerabilities that are hard to detect, hard to exploit, and hard to prevent! If you want to discuss how these issues may apply to your application or have us dive into more detail on a future post, reach out and let us know!