i would like to be able to spot problems with deserialization in java code. What should i look for? For example, how would one determine if some java code tries to exploit "java calendar bug"? Note that i'm not a java programmer, but i understand the concepts behind serialization and OOP fine. I'm trying to implement some safety checks (something like a compiler warning tool).
EDIT: based on comments i would like to change the question a bit: I consider all the code analyzed "untrusted", is there a way how to rate the potential danger? I mean, can i tell that code A is more dangerous than B with regard to deserialization bug? What should i look for?
A Java deserialize vulnerability is a security vulnerability that occurs when a malicious user tries to insert a modified serialized object into the system in order to compromise the system or its data. Think of an arbitrary code execution vulnerability that can be triggered when deserializing a serialized object.
Avoid Deserialization process from creating another instance of Singleton class in java. We can simply use readResove() method to return same instance of class, rather than creating a new one. Defining readResolve() method ensures that we don't break singleton pattern during DeSerialization process.
There are some web application security tools that can help protect against insecure deserialization attacks, such as a web application firewall (WAF), whitelisting and blacklisting.
Unfortunately, the features of these native deserialization mechanisms can be repurposed for malicious effect when operating on untrusted data. Attacks against deserializers have been found to allow denial-of-service, access control, and remote code execution (RCE) attacks.
Firstly you need to understand your context to determine security threats. (When I talk about "trust", I'm taking little short cut. I'm talking deliberately malicious.)
If the serialised data was created, kept and read with the same trust, then there isn't any real problem (other than standard bugs). Note if you write any sensitive information, then the serialised data is also sensitive (it seems obvious, but there is a fair amount of indirection there).
If the the serialised data is untrusted for whatever reason, then there is a little more to consider. The internal structure of the recreated objects may be "unusual". The data may not be consistent. You may have shared mutable objects which should be separate. Deserialisation may cause an infinite loop, or a non-infinite loop which just happens not to be completable before the heat death of the universe. And of course the data may be lies.
If you are writing library code that is used by less trusted code, then things get more interesting:
In the case of "calendar bug" (and similar), that is about deserialising an arbitrary stream with malicious data and malicious code. The Java Secure Coding Guidelines suggests doing security checks (using the "Java2 Security Model") within custom readObject
methods, which implies that you shouldn't call deserialisation with more trust than the code and data has.
From the side of deserialisable objects, things are more tricky. Objects provided by ObjectInputStream
through readObject
, readUnshared
, defaultReadObject
, readFields
or just the default deserialisation may have references captured by malicious code or, for non-final classes, be subclassed maliciously. An object may also be used during deserialisation, when partially initialised. Deserialisation does not invoke a "real" constructor of the deserialised class (readObject
/readObjectNoData
is a kind of psuedo-constructor, which can't set final
s). It's all a bit of a nightmare, so you probably don't want to make your sensitive classes serialisable.
There have been a number of vulnerabilities in the implementation of serialisation and deserialisation. You don't really need to worry about this, unless you are implementing it yourself.
Hmm... your question is a bit general. Did you take a look at this article? It's about Java's serialization algorithm, but from Google's cache because the main page seems to be down at the moment.
I'd have thought that the best way to defeat code that exploits known security holes in Java is to upgrade to a Java version that fixes the bug. And the next best way (to deal with serialization related bugs) is treat all serialized data from unknown / unverified / insecure sources as suspicious.
Trying to spot problems by analyzing java code for security bugs isn't easy, and requires a deep understanding of the Java mechanisms that are being used and could be exploited. Trying to spot attempted exploits (in general) would be even harder, especially if you are looking for exploits for zero-day security holes. Bear in mind that there are other potential vectors.
(If there were easy ways to find unknown security holes in Java, you can bet that Sun and other security researchers would have already used them.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With