...
Noncompliant Code Example (BigInteger
)
Wiki Markup |
---|
This noncompliant code example uses the |
immutable {{java.math.BigInteger}} class. |
Code Block |
---|
|
class BigInteger {
// ...
}
|
Wiki Markup |
---|
The This 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 could construct a spurious mutable {{BigInteger}} instance by overriding {{BigInteger}}'s member functions \[[Bloch 2008|AA. Bibliography#Bloch 08]\]. |
...
Code Block |
---|
|
public class BigInteger {
public BigInteger(String str) {
this( str, check( this.getClass())); // throws a security exception if not allowed
}
private BigInteger(String str, boolean securityManagerCheck) {
// regular construction goes here
}
private static boolean check(Class c) {
// Confirm class type
if (c != BigInteger.class) {
// Check the permission needed to subclass BigInteger
securityManagerCheck(); // throws a security exception if not allowed
}
return true;
}
}
|
Risk Assessment
Noncompliant Code Example (Data-Driven Execution)
Code in privileged blocks should be as simple as possible, both to improve reliability and also to ease security audits. Invocation of overridable methods permits modification of the code that is executed in the privileged context without modification of previously-audited classes. Furthermore, calling overridable methods disperses the code over multiple classes, complicating determination of which specific code must be audited. Malicious subclasses cannot directly exploit this issue because privileges are dropped as soon as unprivileged code is executed. Nevertheless, maintainers of the subclasses might unintentionally violate the requirements of the base class. For example, even when the base class's overridable method is thread-safe, a subclass might provide an implementation that lacks this property, leading to security vulnerabilities.
This noncompliant code example invokes an overridable getMethodName()
method in the privileged block using the reflection mechanism.
Code Block |
---|
|
public class MethodInvoker {
public void invokeMethod() {
AccessController.doPrivileged(new PrivilegedAction<Object>() {
public Object run() {
try {
Class<?> thisClass = MethodInvoker.class;
String methodName = getMethodName();
Method method = thisClass.getMethod(methodName, null);
method.invoke(new MethodInvoker(), null);
} catch (Throwable t) {
// Forward to handler
}
return null;
}
});
}
String getMethodName() {
return "someMethod";
}
public void someMethod() {
// ...
}
// Other methods
}
|
A subclass can override getMethodName()
to return a string other than someMethod
. If an object of such a subclass runs invokeMethod()
, control flow will divert to some mothod other than someMethod
.
Compliant Solution (final
)
This compliant solution declares the getMethodName()
method final so that it cannot be overridden.
Code Block |
---|
|
final String getMethodName() {
// ...
}
|
Alternative approaches that prevent overriding of the getMethodName()
method include declaring it as private or declaring the enclosing class as final.
Compliant Solution (disallow polymorphism)
This compliant solution specifically invokes the correct getMethodName()
, preventing diversion of control flow.
Code Block |
---|
|
public void invokeMethod() {
AccessController.doPrivileged(new PrivilegedAction<Object>() {
public Object run() {
try {
Class<?> thisClass = MethodInvoker.class;
String methodName = MethodInvoker.this.getMethodName();
Method method = thisClass.getMethod(methodName, null);
method.invoke(new MethodInvoker(), null);
} catch (Throwable t) {
// Forward to handler
}
return null;
}
});
}
|
Risk Assessment
Permitting a non-final class or method to be inherited without checking the class instance allows a malicious subclass to misuse the privileges of the class.
...
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]\] Java Insecurity: Accounting for Subtleties That Can Compromise Code
\[[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]\] Secure Coding Guidelines for the Java Programming Language, version 3.0
\[[Ware 2008|AA. Bibliography#Ware 08]\] |
...
04. Object Orientation (OBJ) 04. Object Orientation (OBJ) OBJ01-J. Declare data members as private and provide accessible wrapper methods