2017 OWASP Top 10 for PHP Developers Part 8: Insecure Deserialization

2017 OWASP Top 10 for PHP Developers Part 8: Insecure Deserialization

When developing a web application, web developers sometimes need to first turn data into a proper format so that it can be processed. Occasionally, converting data into a proper format is a requirement in order for it to be stored in a file, database or simply to boost effectiveness. Here’s where serialization comes in – serialization in web applications covers turning data into a stream of bytes so that it can be, for example, stored in a database or in a file. Deserialization is the opposite of serialization – deserialization covers taking structured data and turning it into an object.

Defining insecure deserialization

Insecure deserialization occurs when deserialized data is not validated thus allowing an attacker to tamper an object so that a web application can deserialize an object supplied an attacker. Or, as OWASP describes it, insecure deserialization occurs when malformed data or unexpected data that can be used to abuse application logic, deny service or execute arbitrary code:

Threat Agents / Attack Vectors Security Weakness Impacts
App Specific Exploitability: 1
Prevalence: 2
Detectability: 2
Technical: 3
Business: ?
Exploitation of deserialization is somewhat difficult, as off the shelf exploits rarely work without changes or tweaks to the underlying exploit code. This issue is included in the Top 10 based on an industry survey and not on quantifiable data.
Some tools can discover deserialization flaws, but human assistance is frequently needed to validate the problem. It is expected that prevalence data for deserialization flaws will increase as tooling is developed to help identify and address it.
The impact of deserialization flaws cannot be overstated. These flaws can lead to remote code execution attacks, one of the most serious attacks possible.
The business impact depends on the protection needs of the application and data.

Insecure deserialization occupies the eighth place on the 2017 OWASP Top 10 – this vulnerability is seen on the list for the first time. In the list compiled in 2013, this place was occupied by Cross-Site Request Forgery (CSRF). It is hard to tell how prevalent insecure deserialization is because its inclusion in the 2017 OWASP Top 10 is based on data derived from a survey, but the fact that it pushed out Cross-Site Request Forgery off the list and occupied its place definitely is concerning.

Before you say such a vulnerability is next to harmless, let me remind you that Equifax was breached when hackers exploited an Apache Struts vulnerability which was based on insecure deserialization. Apache was first notified of the vulnerability in 2017 February 14 and released a fix for it on 2017 March 6 – that’s twenty days. Hackers could have breached many, many more web applications during that timeframe.

Anatomy of an insecure deserialization attack

Imagine you own a PHP-based forum and you utilize PHP object serialization to store a supercookie, that is, a type of a cookie that is permanently stored on a computer. The supercookie includes information about a user: it might include their ID, username, rank, a password hash and some other miscellaneous information. The supercookie’s format could look something like this (ID:username:rank:hash:miscellaneous):

1:bob:user:bed128365216c019988915ed3add75fb:abc

Now imagine your web application does not sanitize user input, so an attacker is able to insert some serialized data. That is where your web application could start facing problems, because when attacker-supplied data would be deserialized, a malicious payload could be triggered. A nefarious party might alter the supercookie and then the supercookie might look like this:

1:attacker:administrator:bed128365216c019988915ed3add75fb:xyz

Because the user input was not validated, an attacker was able to change the serialized object and give himself administrative privileges.

If your web application is susceptible to insecure deserialization and the example above did not seem worth paying attention to, consider the fact that such flaws can lead to remote code execution (RCE) vulnerabilities. In other words, if your web application is vulnerable to insecure deserialization, an attacker might be able to run an arbitrary script or execute arbitrary code on your server.

Detecting insecure deserialization

So, how do you determine if your web application is vulnerable to insecure deserialization? Automatic vulnerability scanners are helpful, but in this case, a human review of the code is frequently required too.

Below, you can see a code block that is vulnerable to insecure deserialization (code snippet courtesy of NotSoSecure):

Take a look at it – what do you reckon is happening here?

In the code block shown above, the vulnerability resides at line #17 – user input is not being validated before being passed to the unserialize() function, meaning that any – any – user (or attacker) supplied input would be unserialized.

I have patched both flaws. Here’s how:

In the example above, the code block is no longer susceptible to insecure deserialization – I have patched the vulnerability by utilizing white-list input validation. In other words, I have created an array of allowed values – if the GET parameter “session_filename” does not contain one of those values, the request would get blocked. The web application can no longer deserialize tampered objects supplied by an attacker.

Wait – did you notice I said both flaws have been patched? Does that mean the code block was susceptible to two security vulnerabilities at the same time? Yes, yes it does – the code snippet was also vulnerable to Cross-Site Scripting (XSS). The Cross-Site Scripting vulnerability resided at line #12 – had a developer wrapped the variable “file_name” with htmlentities() or htmlspecialchars(), this wouldn’t be the case, but here we are.

Mitigating insecure deserialization

You have performed a penetration test on your web application and you have determined that your web application is vulnerable to insecure deserialization. The question is, what should you do now? Insecure deserialization can be patched in a number of different ways – I will cover a few of them.

The first thing you should probably consider doing is validating user input. Sanitizing user input is extremely important for any web application, and, if utilized properly, can allow developers to mitigate more than one of the 2017 OWASP Top 10 vulnerabilities. Besides sanitization, you could also consider utilizing a Web Application Firewall (WAF) in order to protect your web application. When a Web Application Firewall is in place, it could detect any insecure deserialization attempts, stop them and notify you before any damage would be done. Or, if you feel those two solutions are not sufficient, monitor the serialization process. Monitoring the serialization process could help catch a potentially malicious payload and prevent attacks that could be conducted by a malicious party.

Summary

While the exploitation of insecure deserialization might be difficult, the fact that such a vulnerability can lead to remote code execution means that insecure deserialization is not a flaw that should be taken lightly. If you’re still not sure whether insecure deserialization is a risk that’s worth protecting against, the Equifax breach in 2017 should put all doubts to rest. And if you happen to need just a bit more guidance on how to protect against it, read the OWASP Deserialization Cheat Sheet.