Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: added NCCE/CS based on CVE-2012-0507

...

Code Block
bgColor#ccccff
public final class Lottery {	
  // ...
}

Noncompliant Code Example (AtomicReferenceArray<>)

CVE-2012-0507 describes an exploit that managed to bypass Java's applet security sandbox and run malicious code on a remote user's machine. The exploit deserialized a malicious object that subverted Java's type system. The malicious object was an array of two objects. The second object was an AtomicReferenceArray<> whose internal array was the first object. However, while the first object was an array of Help objects (which inherited from ClassLoader, the AtomicReferenceArray<>'s internal array is an array of Object. This meant that the malicious code could use AtomicReferenceArray.set(ClassLoader) to create a Help object. (Creation of class loaders is forbidden by the applet security manager.)

This exploit worked because in Java versions prior to 1.7.0_02 the AtomicReferenceArray<> object performed no validation on its internal array.

Code Block
bgColor#ffcccc
langjava
public class AtomicReferenceArray<E> implements java.io.Serializable {
  private static final long serialVersionUID = -6209656149925076980L;

  // Rest of class...
  // No readObject() method, relies on default readObject
}

Compliant Solution (AtomicReferenceArray<>)

This exploit was mitigated in Java 1.7.0_03 by having the AtomicReferenceArray<> validate its array upon deserialization. The readObject() method inspects the array contents, and if the array is of the wrong type, it copies the array, foiling the exploit.

Code Block
bgColor#ccccff
langjava
public class AtomicReferenceArray<E> implements java.io.Serializable {
  private static final long serialVersionUID = -6209656149925076980L;

  // Rest of class...

  /**
   * Reconstitutes the instance from a stream (that is, deserializes it).
   * @param s the stream
   */
  private void readObject(java.io.ObjectInputStream s)
    throws java.io.IOException, ClassNotFoundException {
    // Note: This must be changed if any additional fields are defined
    Object a = s.readFields().get("array", null);
    if (a == null || !a.getClass().isArray())
      throw new java.io.InvalidObjectException("Not array type");
    if (a.getClass() != Object[].class)
      a = Arrays.copyOf((Object[])a, Array.getLength(a), Object[].class);
    unsafe.putObjectVolatile(this, arrayFieldOffset, a);
  }
}

Risk Assessment

Using the default serialized form for any class with implementation-defined invariants may result in the malicious tampering of class invariants.

...

[API 2006]

Class Object, Class Hashtable

[Bloch 2008]

Item 75, Consider using a custom serialized form

[Greanier 2000]

 

[Harold 1999]

Chapter 11, Object Serialization, Validation

[Hawtin 2008]

Antipattern 8. Believing deserialisation is unrelated to construction

 

Metasploit: Java AtomicReferenceArray Type Violation Vulnerability

 

      13. Serialization (SER)