Never use the clone method for defensive copying of untrusted method parameters. Making defensive copies of mutable method parameters mitigates against a variety of security vulnerabilities; see OBJ06-J. Defensively copy mutable inputs and mutable internal components for additional information. However, inappropriate use of the clone()
method can allow an attacker to exploit vulnerabilities by providing arguments that pass initial validation appear normal but subsequently return unexpected values. Such objects may consequently bypass validation and security checks. Never use the clone method When such a class might be passed as an argument to a method, treat the argument as untrusted, and do not use the clone()
method provided by the class. Also, do not use the clone()
method of nonfinal classes to make defensive copies of objects that are instances of classes that both are nonfinal and provide a clone()
method.
This guideline is a specific instance of OBJ57-J. Do not rely on methods that can be overridden by untrusted code.
Noncompliant Code Example
This noncompliant code example defines a validateValue()
method that validates a time value:
Code Block | ||
---|---|---|
| ||
private Boolean validateValue(long time) { // Perform validation return true; // If the time is valid } private void storeDateinDBstoreDateInDB(java.util.Date date) throws SQLException { final java.util.Date copy = (java.util.Date)date.clone(); if (validateValue(copy.getTime())) { Connection con = DriverManager.getConnection("jdbc:microsoft:sqlserver://<HOST>:1433","<UID>","<PWD>"); PreparedStatement pstmt = con.prepareStatement("UPDATE ACCESSDB SET TIME = ?"); pstmt.setLong(1, copy.getTime()); // ... } } |
The storeDateinDBThe storeDateInDB()
method accepts an untrusted date argument and attempts to make a defensive copy using the its clone()
method. The attacker can override the getTime()
method so that it returns a time that passes validation when getTime()
is called for the first time but returns an unexpected value when it is called a second time.. This allows an attacker to take control of the program by creating a malicious date class that extends Date
. If the attacker's code runs with the same privileges as storeDateInDB()
, the attacker merely embeds malicious code inside their clone()
method:
Code Block | ||
---|---|---|
| ||
class MaliciousDate extends java.util.Date {
@Override
public MaliciousDate clone() {
// Malicious code goes here
}
}
|
If, however, the attacker can only provide a malicious date with lessened privileges, the attacker can bypass validation but still confound the remainder of the program. Consider this example:
Code Block | ||
---|---|---|
| ||
public class MaliciousDate extends java.util.Date { private static int count = 0; @Override public long getTime() { java.util.Date d = new java.util.Date(); return (count++ == 1) ? d.getTime() : d.getTime() - 1000; } } } |
This malicious date will appear to be a benign date class the first time that getTime()
is invoked. This allows it to bypass validation in the storeDateInDB()
method. However, the time that is actually stored in the database will be incorrect.
Compliant Solution
This compliant solution avoids using the clone()
method. Instead, it creates a new java.util.Date
object that is subsequently used for access control checks and for insertion into the database:
Code Block | ||
---|---|---|
| ||
private void storeDateinDBstoreDateInDB(java.util.Date date) throws SQLException { final java.util.Date copy = new java.util.Date(date.getTime()); if (validateValue(copy.getTime())) { Connection con = DriverManager.getConnection("jdbc:microsoft:sqlserver://<HOST>:1433","<UID>","<PWD>"); PreparedStatement pstmt = con.prepareStatement("UPDATE ACCESSDB SET TIME = ?"); pstmt.setLong(1, copy.getTime()); // ... } } |
Noncompliant Code Example (CVE-2012-0507)
This noncompliant code example shows a constructor of the Java core class AtomicReferenceArray
present in the Java 1.7.0 update 2:
Code Block | ||||
---|---|---|---|---|
| ||||
public AtomicReferenceArray(E[] array) {
// Visibility guaranteed by final field guarantees
this.array = array.clone();
}
|
This class was subsequently used by the Flashback exploit that infected 550,000 Macintosh computers in April 2012.1
Compliant Solution (CVE-2012-0507)
In Java 1.7.0 update 3, the constructor was modified to use the Arrays.copyOf()
method instead of the clone()
method, as follows:
Code Block | ||||
---|---|---|---|---|
| ||||
public AtomicReferenceArray(E[] array) {
// Visibility guaranteed by final field guarantees
this.array = Arrays.copyOf(array, array.length, Object[].class);
}
|
Applicability
Using the clone()
method to copy untrusted arguments affords attackers the opportunity to bypass validation and security checks.execute arbitrary code.
Automated Detection
Tool | Version | Checker | Description | ||||||
---|---|---|---|---|---|---|---|---|---|
Parasoft Jtest |
| CERT.MET52.CIFC | Only "clone()" instances of "final" classes |
Bibliography
1 "Exploiting Java Vulnerability CVE-2012-0507 Using Metasploit" is shared by user BreakTheSec on Slideshare.net (July 14, 2012). www.slideshare.net/BreakTheSec/exploiting-java-vulnerability.
...