...
A method which receives an untrusted, non-final input argument must beware that other methods or threads might modify the input object. Some methods try to prevent modification by making a local copy of the input object. This does not provide sufficient protection, as a shallow copy of an object may still allow it to point to mutable sub-objects, which may still be modified by other methods or threads. Some methods go farther and perform a deep copy of the input object. This mitigates the problem of modifiable sub-objects, but the method might still be passed a mutable object that estends the input object class.
Noncompliant Code Example (BigInteger
)
In this This noncompliant code example , a malicious class can extend the public
non-final parent class, NonFinal
. Consequently, the attacker can invoke any of the parent class's accessible instance methods, can access the parent class's protected
fields, and can even override any of the parent class's accessible non-final methodsuses the immutable java.math.BigInteger
class.
Code Block |
---|
|
class BigInteger {
// ...
}
|
Wiki Markup |
---|
The class is non-final and consequently extendable. This can be a problem when operating on an instance of {{BigInteger}} that was obtained from an untrusted client. For example, a malicious client may construct a spurious mutable {{BigInteger}} instance by overriding {{BigInteger}}'s member functions \[[Bloch 2008|AA. Bibliography#Bloch 08]\]. |
The following code example demonstrates such an attack.
Code Block |
---|
|
BigInteger msg = new BigInteger("123");
msg = msg.modPow(exp, m); // Always returns 1
// Malicious subclassing of java.math.BigInteger
class BigInteger extends java.math.BigInteger {
private int value;
public BigInteger(String str) {
super(str);
value = Integer.parseInt( str);
}
public class NonFinal {
public NonFinalsetValue(int value) {
this.value = value;
}
@Override public java.math.BigInteger modPow(java.math.BigInteger exponent, java.math.BigInteger m) {
// this.value = ((int) (Math.pow( this.value, exponent))) % m;
return this;
}
}
|
This malicious BigInteger
class is clearly mutable, thanks to the setValue()
method. Furthermore, the modPow()
method is subject to precision loss (see NUM00-J. Ensure that integer operations do not result in overflow, NUM06-J. Check floating point inputs for exceptional values, NUM15-J. Ensure conversions of numeric types to narrower types do not result in lost or misinterpreted data and NUM10-J. Beware of precision loss when converting primitive integers to floating-point for more info). Any code that receives an object of this class, and assumes it is imutable will have unexpected behavior. (The BigInteger.modPow()
method has several useful cryptographic applications.)
Noncompliant Code Example (Security Manager)
Wiki Markup |
---|
This noncompliant code example installs a security manager check in the constructor of the non-final parent{{BigInteger}} class. The security manager denies access when it detects that a subclass without the requisite permissions is attempting to instantiate the superclass \[[SCG 2007|AA. Bibliography#SCG 07]\]. It also compares class types, in compliance with [OBJ06-J. Compare classes and not class names]. |
Code Block |
---|
|
public class NonFinalBigInteger {
public NonFinalBigInteger(String str) {
Class c = getClass(); // java.lang.Object.getClass(), which is final
// Confirm class type
if (c != NonFinal.class) {
// Check the permission needed to subclass NonFinal
securityManagerCheck(); // throws a security exception if not allowed
}
// ...
}
}
|
Unfortunately, throwing an exception from the constructor of a non-final class is insecure because it allows a finalizer attack (see guideline OBJ04-J. Do not allow access to partially initialized objects).
Compliant Solution (final
)
This compliant solution prevents creation of malicious subclasses by declaring the immutable BigInteger
class to be final
. Although this solution would be appropriate for locally maintained code, it cannot be used in the case of java.math.BigInteger
because it would require changing the Java SE API, which has already been published and must remain compatible with previous versions.
Code Block |
---|
|
final class BigInteger {
// ...
}
|
Compliant Solution (Class Sanitization)
Wiki Markup |
---|
When instances of non-final classes are obtained from untrusted sources, such instances should be used with care, because their method calls might be overridden by malicious methods. This potential vulnerability can be mitigated by making defensive copies of the acquired instances prior to use. This compliant solution demonstrates this technique for a {{BigInteger}} argument \[[Bloch 2008|AA. Bibliography#Bloch 08]\]. |
Code Block |
---|
|
public static BigInteger safeInstance(BigInteger val) {
// create a defensive copy if it is not java.math.BigInteger
if (val.getClass() != java.math.BigInteger.class)
return new BigInteger(val.toByteArray());
return val;
}
|
The guidelines FIO00-J. Defensively copy mutable inputs and mutable internal components and OBJ10-J. Provide mutable classes with copy functionality to allow passing instances to untrusted code safely discuss defensive copying in great depth.
Compliant Solution (Java SE 6+, public and private constructors)
...
Code Block |
---|
|
public class NonFinalBigInteger {
public NonFinalBigInteger(String str) {
this( str, check( this.getClass())); // throws a security exception if not allowed
}
private NonFinalBigInteger(String str, boolean securityManagerCheck) {
// regular construction goes here
}
private static boolean check(Class c) {
// Confirm class type
if (c != NonFinalBigInteger.class) {
// Check the permission needed to subclass NonFinalBigInteger
securityManagerCheck(); // throws a security exception if not allowed
}
return true;
}
}
|
...
Search for vulnerabilities resulting from the violation of this guideline on the CERT website.
Bibliography
Wiki Markup |
---|
\[[API 2006|AA. Bibliography#API 06]\] Class BigInteger
\[[Bloch 2008|AA. Bibliography#Bloch 08]\] Item 1: "Consider static factory methods instead of constructors"
\[[Gong 2003|AA. Bibliography#Gong 03]\] Chapter 6: "Enforcing Security Policy"
\[[Lai 2008|AA. Bibliography#Lai 08]\]
\[[McGraw 2000|AA. Bibliography#McGraw 00]\] Chapter Seven Rule 3: "Make Everything Final, Unless There's a Good Reason Not To"\[[SCG 2007|AA. Bibliography#SCG 07]\] Guideline 1-2 "Limit the extensibility of classes and methods"
\[[SCG 2009|AA. Bibliography#SCG 09]\] |
...