Unrestricted deserializing from a privileged context allows an attacker to supply crafted input which, upon deserialization, can yield objects that the attacker lacks would otherwise lack permissions to construct. One example is the construction of a sensitive object such as a custom class loader. Consequently, avoid deserializing from a privileged context. When deserializing requires privileges, programs must strip all permissions other than the minimum set required for the intended usage.
...
The default security model of an applet does not allow access to sun.util.calendar.ZoneInfo
because applets cannot be permitted to invoke any method from any class within the sun
package. As a result, prior to JDK 1.6 u11, the acceptable method for an unsigned applet to deserialize a ZoneInfo
object was to execute the call from a privileged context, such as a doPrivileged()
block. This constitutes a vulnerability because there is no guaranteed method of knowing whether the serialized stream contains a bona fide ZoneInfo
object rather than a malicious serializable class. The vulnerable code casts the malicious object to the ZoneInfo
type, which typically causes a ClassCastException
if the actual deserialized class is not a ZoneInfo
object. This exception, however, is of little consequence because it is possible to store a reference to the newly created object in a static context so that the garbage collector does not cannot act upon it.
A nonserializable class can be extended and its subclass can be made serializable. Also, a subclass automatically becomes serializable if it derives from a serializable class. During deserialization of the subclass, the JVM calls the no-argument constructor of the most derived superclass that does not implement java.io.Serializable
either directly or indirectly. This allows it to fix the state of this superclass. In the following code snippet, class A
's no-argument constructor is called when C
is deserialized because A
does not implement Serializable
. Subsequently, Object
's constructor is invoked. This procedure cannot be carried out programmatically, so the JVM generates the equivalent bytecode at runtime. Typically, when the superclass's constructor is called by a subclass, the subclass remains on the stack. However, in deserialization this does not happen. Only the unvalidated bytecode is present. This allows any security checks within the superclass's constructor to be bypassed in that the complete execution chain is not scrutinized.
...
A custom class loader can be used to exploit this vulnerability. Instantiating a class loader object requires special permissions that are made available by the security policy that is enforced by the SecurityManager
. An unsigned applet cannot carry out this step by default. If However, if an unsigned applet can execute a custom class loader's constructor, it can effectively bypass all the security checks (it has the requisite privileges as a direct consequence of the vulnerability). A custom class loader can be designed to extend the system classlLoader, undermine security, and carry out prohibited actions such as reading or deleting files on the user's file system. Moreover, legitimate security checks in the constructor are meaningless because the code is granted all privileges. The following noncompliant code example illustrates the vulnerability.
Code Block | ||
---|---|---|
| ||
try { ZoneInfo zi = (ZoneInfo) AccessController.doPrivileged( new PrivilegedExceptionAction() { public Object run() throws Exception { return input.readObject(); } }); if (zi != null) { zone = zi; } } catch (Exception e) { // handle error } |
Compliant Solution (CVE-2008-5353: Zoneinfo
)
...
<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="1d6baeed67c94505-59f81b32-463a4a98-b4a5a0e3-646dfdc6687ac3deb75297d5"><ac:plain-text-body><![CDATA[ | [[API 2006 | AA. Bibliography#API 06]] |
| ]]></ac:plain-text-body></ac:structured-macro> | |
<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="01cd9eabc536fbfe-a55ac035-48f8417f-9a5da656-3f56996b1341ad86e21a66df"><ac:plain-text-body><![CDATA[ | [[CVE 2011 | AA. Bibliography#CVE 08]] | [CVE-2008-5353 | http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2008-5353] | ]]></ac:plain-text-body></ac:structured-macro> |
...