Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

Classes containing private, confidential, or otherwise sensitive data are best not copied. If a class is not meant to be copied, then failing to define copy mechanisms, such as a copy constructor, is insufficient to prevent copying.

Java's Object object cloning mechanism can allow allows an attacker to manufacture new instances of a class that has been defined without executing its constructor. If a class is not cloneable, the attacker can define a subclass and make the subclass implement the java.lang.Cloneable interface. This lets the attacker create new instances of the class. The new instances of the class are made by copying the memory images of existing objects. Although this is sometimes an acceptable way of making a new object, it often is not.

Noncompliant Code Example

by copying the memory images of existing objects rather than by executing the class's constructor. Often, this is an unacceptable way of creating new objects. An attacker can misuse the clone feature to manufacture multiple instances of a singleton class, create thread-safety issues by subclassing and cloning the subclass, bypass security checks within the constructor, and violate the invariants of critical data.

Classes that have security checks in their constructors must beware of finalization attacks, as explained in OBJ11-J. Be wary of letting constructors throw exceptions.

Classes that are not sensitive but maintain other invariants must be sensitive to the possibility of malicious subclasses accessing or manipulating their data and possibly invalidating their invariants (see OBJ04-J. Provide mutable classes with copy functionality to safely allow passing instances to untrusted code for more information).

Noncompliant Code Example

This noncompliant code example defines class SensitiveClass, which contains a character array used to hold a file name, along with a Boolean shared variable, initialized to false. This data is not meant to be copied; consequently, SensitiveClass lacks a copy constructorConsider the following class definition. Unless someone knows the secret password, objects cannot be created because the constructor for the class checks for the password stored in some password file.

Code Block
bgColor#ffcccc

class MyPrivacySensitiveClass {

  private  //define class member fields
    //...char[] filename;
  private Boolean shared = false;

    public MyPrivacySensitiveClass(String passwdfilename) {
        String actualPass;
        FileReader frthis.filename = new FileReader("Passfile.txt"filename.toCharArray();
  }

  final void replace() {
 BufferedReader br = newif BufferedReader(fr!shared); {
      for(int  actualPassi = br.readLine()0;
 i <      if(actualPass.equals(passwd))filename.length; i++) {
    	filename[i]= 'x' ;}
    }
  // return normally}

  final String     }get() {
    if    else(!shared) {
      shared = true;
    // exit the program, print an authentication errorreturn String.valueOf(filename);
    } else {
      //throw preventing the class object from being creatednew IllegalStateException("Failed to get instance");
        }

    }

    publicfinal void useprintFilename() {
     //System.out.println(String.valueOf(filename));
    }

    //...
}

When a client requests a String instance by invoking the get() method, the shared flag is set. To maintain the array's consistency with the returned String object, operations that can modify the array are subsequently prohibited. As a result, the replace() method designed to replace all elements of the array with an x cannot execute normally when the flag is set. Java's cloning feature provides a way to circumvent this constraint even though SensitiveClass does not implement the Cloneable interface.

This class can be exploited by a malicious class, shown in the following noncompliant code example, that subclasses the nonfinal SensitiveClass and provides a public clone() method:The attacker can create a new instance of MyPrivacy class by using a cloneable subclass and bypass the constructor. Bypassing the constructor leads to bypassing the password check done in the constructor.

Code Block
bgColor#ffcccc

class TestMaliciousSubclass extends MyPrivacySensitiveClass implements Cloneable {

    public static void somefunction(MyPrivacy objprotected MaliciousSubclass(String filename) {

	try {
   super(filename);
  }

  @Override public MaliciousSubclass clone() { Test t = (Test)obj.// Well-behaved clone() method
    MaliciousSubclass s =  }catch(Exception e)null;
    try {
      s      System.out.println("not cloneable"= (MaliciousSubclass)super.clone();
        }
        if (t != null) catch(Exception e) {
            t.use(); // Another object instantiated without knowing the password.....System.out.println("not cloneable");
    }
}

Compliant Solution

Classes should be made noncloneable to prevent this from occurring. The following method may be implemented to achieve this.

Code Block
bgColor#ccccff
class MyPrivacy {
    //define class member fieldsreturn s;
    //...}

  public static publicvoid MyPrivacymain(String[] passwdargs) {
        String actualPass;
        FileReader fr MaliciousSubclass ms1 = new FileReaderMaliciousSubclass("Passfilefile.txt");
        BufferedReader brMaliciousSubclass ms2 = new BufferedReader(frms1.clone();
 // Creates a copy
    actualPassString s = brms1.readLineget();
  // Returns filename
    if(actualPass.equals(passwd)){
            System.out.println(s); // returnFilename normally
        }is "file.txt"
    ms2.replace();    else{
            // exitReplaces theall program,characters print an authentication error
  with 'x'
          // preventing the class object from being created
        }
Both ms1.get() and ms2.get() will subsequently return filename = 'xxxxxxxx'
    }

    public void use(){
  ms1.printFilename();   //
 Filename   }
becomes 'xxxxxxxx'
    //...
    public final void clonems2.printFilename(); throws java.lang.CloneNotSupportedException{
       throw new java.lang.CloneNotSupportedException();
    }
}

Compliant Solution

 // Filename becomes 'xxxxxxxx'
  }
}

The malicious class creates an instance ms1 and produces a second instance ms2 by cloning the first. It then obtains a new filename by invoking the get() method on the first instance. At this point, the shared flag is set to true. Because the second instance ms2 does not have its shared flag set to true, it is possible to alter the first instance ms1 using the replace() method. This approach obviates any security efforts and severely violates the class's invariants.

Compliant Solution (Final Class)

The easiest way to prevent malicious subclasses is to declare SensitiveClass to be finalOne can also make a class nonsubclassable. This can be achieved by finalizing a class.

Code Block
bgColor#ccccff

&#xA0;final class MyPrivacySensitiveClass {
  // Rest of the definition remains the same
 }

If it is absolutely required to make the class cloneable, even then protective measures can be taken.

...

...
}

Compliant Solution (Final clone())

Sensitive classes should neither implement the Cloneable interface nor provide a copy constructor. Sensitive classes that extend from a superclass that implements Cloneable (and are cloneable as a result) must provide a clone() method that throws a CloneNotSupportedException. This exception must be caught and handled by the client code. A sensitive class that does not implement Cloneable must also follow this advice because it inherits the clone() method from Object. The class can prevent subclasses from being made cloneable by defining a final clone() method that always fails.

Code Block
bgColor#ccccff
class SensitiveClass {
  // ...
  public final 

...

SensitiveClass clone() 
                              throws 

...

CloneNotSupportedException {
    throw 

...

new CloneNotSupportedException();
  }
}

This class fails to prevent malicious subclasses but does protect the data in SensitiveClass. Its methods are protected by being declared final. For more information on handling malicious subclasses, see OBJ04-J. Provide mutable classes with copy functionality to safely allow passing instances to untrusted code.

Risk Assessment

...

Failure to make sensitive classes noncopyable can permit violations of class invariants and provide malicious subclasses with the opportunity to exploit the code to create new instances of objects, even in the presence of the default security manager (in the absence of custom security checks).

Rule

Recommendation

Severity

Likelihood

Remediation Cost

Priority

Level

MSC05

OBJ07-J

medium

Medium

probable

Probable

medium

Medium

P8

L2

References

Wiki Markup
\[[Mcgraw 98|AA. Java References#Mcgraw 98]\] 
\[[Wheeler 03|AA. Java References#Wheeler 03]\] 10.6. Java 
\[[MITRE 09|AA. Java References#MITRE 09]\] [CWE ID 498|http://cwe.mitre.org/data/definitions/498.html] "Information Leak through Class Cloning"

Automated Detection

ToolVersionCheckerDescription
CodeSonar
Include Page
CodeSonar_V
CodeSonar_V

JAVA.CLASS.CLONE.CNC
JAVA.CLASS.CLONE.SCNC
JAVA.CLASS.CLONE.NF

clone Non-cloneable (Java)
clone Subclass of Non-clonable (Java)
clone not final (Java)

Parasoft Jtest
Include Page
Parasoft_V
Parasoft_V
CERT.OBJ07.MCNCMake your classes noncloneable

Related Guidelines

MITRE CWE

CWE-498, Cloneable Class Containing Sensitive Information
CWE-491, Public cloneable() Method without Final (aka "Object Hijack")

Bibliography

[McGraw 1998]

"Twelve Rules for Developing More Secure Java Code"

[Wheeler 2003]

Section 10.6, "Java"


...

Image Added Image Added Image AddedMSC04-J. Be aware of JVM Monitoring and Managing      11. Miscellaneous (MSC)      MSC30-J. Generate truly random numbers