Some classes contain data that must not be copied; these classes can be considered to be sensitive. If a class is not meant to be copied, then failing to define copy mechanisms, such as a copy constructor, is not sufficient insufficient to prevent copying.
Java's object cloning mechanism allows an attacker to manufacture new instances of a class by copying the memory images of existing objects rather than by executing the class's constructor. Often this is not an acceptable way of creating new objects. An attacker can misuse the clone feature to 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.
...
Classes that are not sensitive, but that maintain other invariants must be sensitive to the possibility of malicious subclasses accessing or manipulating their data, and possibly invalidating their invariants. See OBJ10-J. Provide mutable classes with copy functionality to allow passing instances to untrusted code safely for more information.
...
This noncompliant code example defines class SensitiveClass
which contains a character array used to internally hold a filename, along with a Boolean
shared variable, initialized to false
. This data is not meant to be copied; and SensitiveClass
does not provide consequently, SensitiveClass
lacks a copy constructor.
Code Block | ||
---|---|---|
| ||
class SensitiveClass { private char[] filename; private Boolean shared = false; SensitiveClass(String filename) { this.filename = filename.toCharArray(); } final void replace() { if (!shared) for(int i = 0; i < filename.length; i++) { filename[i]= 'x'; } } final String get() { if (!shared) { shared = true; return String.valueOf(filename); } else { throw new IllegalStateException("Failed to get instance"); } } final void printFilename() { System.out.println(String.valueOf(filename)); } } |
...
Code Block | ||
---|---|---|
| ||
class MaliciousSubclass extends SensitiveClass implements Cloneable { protected MaliciousSubclass(String filename) { super(filename); } @Override public MaliciousSubclass clone() { // Well-behaved clone() method MaliciousSubclass s = null; try { s = (MaliciousSubclass)super.clone(); } catch(Exception e) { System.out.println("not cloneable"); } return s; } public static void main(String[] args) { MaliciousSubclass ms1 = new MaliciousSubclass("file.txt"); MaliciousSubclass ms2 = ms1.clone(); // Creates a copy String s = ms1.get(); // Returns filename System.out.println(s); // Filename is "file.txt" ms2.replace(); // Replaces all characters with 'x' // Both ms1.get() and ms2.get() will subsequently return filename = 'xxxxxxxx' ms1.printFilename(); // Filename becomes 'xxxxxxxx' ms2.printFilename(); // Filename becomes 'xxxxxxxx' } } |
It proceeds to create The malicious class creates its own instance (ms1
) and produces a second one (ms2
), by cloning the first. It then obtains a new String
filename
object 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 obviates any security efforts and severely violates the class's invariants.
...
Sensitive classes should not implement the Cloneable
interface, nor provide a copy constructor. Classes Sensitive classes that extend from a superclass that implements Cloneable
(and is consequently cloneable) should 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 cloneable by defining a final
clone()
method that fails.
Code Block | ||
---|---|---|
| ||
class SensitiveClass { // ... public final SensitiveClass clone() throws CloneNotSupportedException { throw new CloneNotSupportedException(); } } |
This does not fails to prevent malicious subclasses, but does protect the data in SensitiveClass
. Its methods are protected by being declared final
. for For more info information on how to handle malicious subclasses, see OBJ10-J. Provide mutable classes with copy functionality to allow passing instances to untrusted code safely.
...
Failure to make sensitive classes non-copyable can severely violate 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).
...