If security checks are based on untrusted sources, it becomes possible to bypass them. It is recommended to defensively copy the untrusted object or parameter before the security check is carried out. For this purpose deep copies must be created as opposed to using the clone()
method to create shallow copies. See guidelines MET08-J. Do not use the clone method to copy untrusted method parameters and FIO00-J. Defensively copy mutable inputs and mutable internal components for more information.
Noncompliant Code Example
This noncompliant code example describes a security vulnerability from JDK 5.0 software. At the time, java.io.File
was non-final, allowing an attacker to supply an untrusted value as a parameter which was constructed by extending the legit java.io.File
class. In this way, the getPath()
method could be overridden so that the security check passes the first time it is called but the value mutates the second time to refer to a sensitive file such as /etc/passwd
. This is a time-of-check-time-of-use (TOCTOU) vulnerability.
Code Block | ||
---|---|---|
| ||
public RandomAccessFile openFile(final java.io.File f) { askUserPermission(f.getPath()); // ... return (RandomAccessFile)AccessController.doPrivileged() { public Object run() { return new RandomAccessFile(f.getPath()); } } } |
The attacker can extend java.io.File
as follows:
Code Block |
---|
public class BadFile extends java.io.File { private int count; public String getPath() { return (++count == 1) ? "/tmp/foo" : "/etc/passwd"; } } |
Compliant Solution
Security checks should not be based on untrusted sources. This compliant solution ensures that the java.io.File
object cannot be untrusted. This is achieved by declaring java.io.File
as final
and ensuring that a new java.io.File
object is created in the openFile()
method. Note that using the clone()
method instead of the openFile()
method would copy the attacker's class, which is not desirable. (Refer to guideline MET08-J. Do not use the clone method to copy untrusted method parameters.)
Code Block | ||
---|---|---|
| ||
public RandomAccessFile openFile(java.io.File f) { final java.io.File copy = new java.io.File(f.getPath()); askUserPermission(copy.getPath()); // ... return (RandomAccessFile)AccessController.doPrivileged() { public Object run() { return new RandomAccessFile(copy.getPath()); } } } |
Risk Assessment
Basing security checks on untrusted sources can result in the check being bypassed.
Guideline | Severity | Likelihood | Remediation Cost | Priority | Level |
---|---|---|---|---|---|
SEC09-J | high | probable | medium | P12 | L1 |
Automated Detection
TODO
Related Vulnerabilities
Search for vulnerabilities resulting from the violation of this rule on the CERT website.
References
Wiki Markup |
---|
\[[Sterbenz 2006|AA. Java References#Sterbenz 06]\] \[[MITRE 2009|AA. Java References#MITRE 09]\] [CWE ID 302|http://cwe.mitre.org/data/definitions/302.html] "Authentication Bypass by Assumed-Immutable Data" |
SEC08-J. Enforce security checks in code that performs sensitive operations 02. Platform Security (SEC) SEC10-J. Define custom security permissions for fine grained security