Hello everyone!! Serialization is a concept that is being implemented for very long, but the vulnerability has got much traction in recent years. In the OWASP top 10 list, 2017, insecure deserialization is positioned at 8th which has furthermore attracted hackers and pentesters to explore on the vulnerability.
So lets deep-dive in understanding what exactly is serialization.
It is a process of converting structured data to a format that allows sharing or storage of the data in a form that allows recovery of its original structure.
Serialization is widely used in the world of programming as it aids in the efficient transmission of objects over the network. Also, serialized objects can be easily stored in databases.
There are many use cases where serialized objects are popularly used.
- Remote- and inter-process communication (RPC/IPC)
- Wire protocols, web services, message brokers
- Databases, cache servers, file systems
- HTTP cookies, HTML form parameters, API authentication tokens
Manipulation of objects becomes very easy when programmers are required to work different programming languages. For instance, when a python object is serialized into json, it can be manipulated by other programming languages such as java, which in either case is impossible to achieve.
Python has support for different modules that perform serialization. They are listed as:
So let’s talk upon one of the excessively used modules, Pickle.
(According to python.org)
The pickle module implements binary protocols for serializing and de-serializing a Python object structure. “Pickling” is the process whereby a Python object hierarchy is converted into a byte stream, and “unpickling” is the inverse operation, whereby a byte stream (from a binary file or bytes-like object) is converted back into an object hierarchy.
Few advantages that pickle offers oven other modules:
- Pickle keeps track of the objects it has already serialized.
- Pickle store object once and ensures that all the references point to the master copy
- Pickle can save and restore class instances.
But the documentation clearly states a warning in Red regarding its implementation
So let’s see, how overlooking this warning can be exploited and has the possibility to even compromise the server.
The above code implementation explains that there is a class named EvilPickle that implements __reduce__ function and returns the system module running the command ls on the present working directory. This class is then serialized using pickle.dumps() to a file named backup.data. When this file is deserialized, we will achieve command execution.
__reduce__ method takes in no arguments and returns either a string or a tuple.
When a tuple is returned, it is 2-6 items long:
- A callable object that will be called to create the initial version of the object.
- A tuple of arguments for the callable object. An empty tuple must be given if the callable does not accept any argument. (Rest options are optional)
Whenever pickling is done, __reduce__ method is automatically called. It helps pickle in serializing the arbitrary objects, for instance, opening or closing a file. Therefore, if any malicious code is returned in __reduce__, you will get command execution.
Insecure deserialization vulnerability is still difficult to find as a lot of code analysis is required, i.e. everything can’t be automated. Developers should be well aware of this vulnerability and should focus on writing secure code.
Here are the few remediations that can save your application from being compromised
- Avoid serialization where it is unnecessary
- Research and use best practices
- Avoid allowing objects from untrusted sources
- Use encryption in transit to avoid tempering
- Use whitelisting of expected types/data
- Sandboxing deserialization
- Logging for suspicious behaviour
Hope you got the basics of serialization/deserialization, how it can be exploited and how to stay safe.
Thanks for reading! If you enjoyed the post, like it and share it and subscribe to my page.