The root cause of many serious security incidents is some vulnerability in the implementation of the serialization-deserialization process. Just recently, such vulnerability was fixed in the WordPress application. Although these vulnerabilities can be extremely harmful, they seem to be less widely understood than the ones that involve direct user input. Therefore, this column is dedicated to taking a deeper look at them.
Understanding the serialization-deserialization process
The process of representing complex structured objects in a flat form, in order to store them (mostly in files and databases) or transmit them over the network, is called serialization.
Object serialization example (Credit XML.com)
The reverse process of creating objects from their serialized, flat form is called deserialization. Serialization- deserialization is a very common practice and it’s being commonly used by applications to achieve persistence, i.e. saving some data stored in the program’s volatile memory into a file or Database, and for the sending of data across the network in distributed computation environments. For many complex objects, this process is not a straightforward one, consisting merely on storing and retrieving data. Sometimes the object contains references to some operating system resources that need to be created or accessed when the object is instantiated via deserialization. For example, the PHPMyAdmin’s configuration object “PMA_config” which will be furtherc discussed below, contains a reference to the system’s configuration file. When a serialized “PMA_config” byte-stream gets deserialized by PHPMyAdmin’s application, the application code try to access the filename specified in the byte stream.
The process of Serialization-Deserialization illustrated (Credit StudyTonight.Com)
The security pitfalls of the deserialization process
From a security perspective, the deserialization process is prone to trouble, as the deserialization process takes some external input and operates according to it, by definition. While security aware developers already know that user supplied data cannot be trusted and must be scrutinized, in the case of deserialization it’s very tempting to assume that the input is legitimate. After all, the input data was created via serialization by some other part of the program and therefore can be trusted.
However, reality shows that this assumption does not always hold true. When it’s proved to be false, as often happens when core assumptions gets broken, the result is catastrophic.
In some cases, this assumption breaks due to design issues that allow users to submit their serialized data directly. This was the case with two Ruby on Rails (RoR) critical vulnerabilities that was discussed in this column in detail a few months ago. In both vulnerabilities the core issue was that RoR input parser was willing to accept serialized data as input and automatically deserialize it. CVE-2013-0155 vulnerability abused the application through the unexpected usage of the JSON serialization format. An attacker using the JSON serialization format can trick a Ruby application which expects its parameters to be of an atomic type (i.e. an integer or a string) and pass a JSON’s array instead. With this unexpected input, the attacker is able to smuggle an empty value (“NULL”) as the only element of an array, and bypass an application specific use of the “IS NULL” check designed for atomic types, as the array itself in not empty. CVE-2013-0156 vulnerability abused the application through the unexpected usage of the XML and YAML serialization format. The attacker could pass a serialized object describing some OS commands. When the input is deserialized, these commands are executed.
In other cases, the assumption breaks due to implementation issues, which allow the attacker to smuggle an arbitrary value into serialized data by abusing some application vulnerability and then leverage it to abuse some deserialization vulnerability. This was the case with the PHPMyAdmin exploit, which Imperva had recently unveiled. In this attack, the attacker can combine multiple vulnerabilities together to inject an arbitrary serialized data. The attacker first abuses PHPMyAdmin’s CVE-2011-2505 vulnerability to inject a value into the session file which is coded in a way that abuses PHP’s CVE-2010-3065 vulnerability to create the aforementioned serialized PMA_Config object. When the PMA_Config object gets deserialized from the session file, the deserialization function evaluates the PMA_Config object and will execute arbitrary PHP commands
Developers should pay some special attention to the implementation of the deserialization functions of an object. Specifically, they should refrain from cutting themselves some slack and use known unsafe practices (e.g. the eval function), under the false assumption that serialized data can be trusted.
Web servers administrators should monitor and be alerted about relevant vulnerabilities to their application that are related to deserialization, as they often prove to be very harmful.