You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 21 Next »

Java's Object cloning mechanism allows an attacker to manufacture new instances of a class, without executing its constructor. The new instances are made by copying the memory images of existing objects. Although this is sometimes an acceptable way of creating new objects, it often is not. By misusing the clone feature, an attacker can manufacture multiple instances of a singleton class, create serious thread-safety issues by subclassing and cloning the subclass, bypass security checks within the constructor and violate the invariants of critical data.

Noncompliant Code Example

Consider the following noncompliant class definition. Unless someone knows the secret password, objects cannot be created. This is because the constructor for the class checks the input against the expected password before allowing object construction. It also performs a security check. The calling code uses a doPrivileged block to create an instance of SensitiveClass. Object creation beyond this block is prohibited by the security manager. However, since the SensitiveClass advertises a public clone() method, it is possible to circumvent this restriction. This clearly violates the principle of least privilege. Yet another blemish is the inconsistent security checking.

class SensitiveClass implements Cloneable {
  protected SensitiveClass(String passwd) {
    // perform security manager check
    System.out.println("SensitiveClass construction done!");
  }

  protected void use(){
    System.out.println("In method use()");
  }

  public SensitiveClass Clone() {  // well-behaved clone() method
    SensitiveClass s = null;
    try {
      s = (SensitiveClass)super.clone();	        
    }catch(Exception e) { System.out.println("not cloneable"); }
  return s;
  }
}

class Foo {
  protected void privileged() {
    final SensitiveClass sc[] = new SensitiveClass[2];

    AccessController.doPrivileged(new PrivilegedAction() {  
      public Object run() {
        sc[0] = new SensitiveClass("password"); // object creation with the password
        sc[0].use();  //allowed
        return null;    
      }		
    });
  
    sc[1] = sc[0].Clone(); // object creation without the password
    sc[0].use();  // this should not be allowed
  }

  public static void main(String[] args) {
    Foo f = new Foo();
    f.privileged();
  }
}

Compliant Solution

Sensitive classes should not implement the Cloneable interface. If the class extends from a superclass that implements Cloneable (and is therefore cloneable), it's clone() method should throw a CloneNotSupportedException. This exception must be caught and handled by the client code.

public SensitiveClass Clone() throws CloneNotSupportedException {
  throw new CloneNotSupportedException();
}

It is also required to declare SensitiveClass final so as to avoid malicious subclassing. This will stop an artful attacker from subclassing the sensitive class and creating several copies of the subclass, with the intention of introducing thread-safety issues.

Risk Assessment

Recommendation

Severity

Likelihood

Remediation Cost

Priority

Level

MSC05-J

medium

probable

medium

P8

L2

References

[[Mcgraw 98]]
[[Wheeler 03]] 10.6. Java
[[MITRE 09]] CWE ID 498 "Information Leak through Class Cloning", CWE ID 491 "Public cloneable() Method Without Final (aka 'Object Hijack')"


MSC04-J. Be aware of JVM Monitoring and Managing      49. Miscellaneous (MSC)      MSC30-J. Generate truly random numbers

  • No labels