SV.PRIVILEGE.MISSING
Method invoked should not be inside doPrivileged block
The software does not properly assign, modify, track, or check privileges for an actor, creating an unintended sphere of control for that actor.
Vulnerability and risk
The security checks associated with loading classes are performed by class loaders. Consequently, any method that invokes one of these class loading methods must guarantee that these methods cannot act on behalf of untrusted code.
java.lang.Runtime.load
java.lang.Runtime.loadLibrary
java.lang.System.load
java.lang.System.loadLibrary
java.lang.reflect.Field.setAccessible()
Vulnerable code example 1
In the example below we see evidence of a privilege change.
public class NoReturnNoException {
public void somemethod() {
AccessController.doPrivileged(new PrivilegedAction<Void>() {
public Void run() {
// Privileged code goes here, for example:
System.loadLibrary("awk");
return null; // nothing to return
}
});
}
}
public class NoReturnNoException {
class MyAction implements PrivilegedAction<Void> {
public Void run() {
// Privileged code goes here, for example:
System.loadLibrary("awt");
return null; // nothing to return
}
}
public void somemethod() {
MyAction mya = new MyAction();
// Become privileged:
AccessController.doPrivileged(mya);
}
}
This code is insecure because it could load a library on behalf of untrusted code. The untrusted code's class loader may be able to use this code to load a library even though it lacks sufficient permissions to do so directly. After loading the library, the untrusted code can call native methods from the library, if those methods are accessible, because the doPrivileged block stops any security manager checks from being applied to callers further up the execution stack.
The example using a lambda expression.
import java.security.*;
public class NoReturnNoException {
public void somemethod() {
// Lambda expression
AccessController.doPrivileged((PrivilegedAction<Void>)
() -> {
// Privileged code goes here, for example:
System.loadLibrary("awt");
return null; // nothing to return
}
);
}
}
The loadLibrary() method should not be used in a doPrivileged block to avoid permission overwriting.
Fixed code example 1
import java.security.*;
public class NoReturnNoException {
public void somemethod() {
System.loadLibrary("awt");
}
}
In this example, Klocwork no longer reports a defect as the loadLibrary() method is not used in a doPrivileged block.
Vulnerable code example 2
AccessController.doPrivileged(new PrivilegedAction() {
@Override
public Object run() {
field.setAccessible(true); // <----- SV.PRIVILEGE.MISSING should not be in doPrivileged block
return null;
}
});
In this example, the java.lang.reflect.Field.setAccessible() method is used to instruct the Java Virtual Machine (JVM) to override the language access checks. Wrapping this method in AccessController.doPrivileged will grant permission, regardless of the permissions of the caller code. These methods should be used with extreme caution.
The example using a lambda expression:
AccessController.doPrivileged((PrivilegedAction) () -> {
field.setAccessible(true); // <----- SV.PRIVILEGE.MISSING should not be in doPrivileged block
return null;
});
Fixed code example 2
public static void replaceNull(Object obj)
{
Field[] fields = obj.getClass().getDeclaredFields();
if (fields != null)
{
for (Field field : fields)
{
field.setAccessible(true);
}
}
}
In this example, Klocwork no longer reports a defect as the field.setAccessible( ) method is not used in a doPrivileged block.
Related checkers
External guidance
Security training
Application security training materials provided by Secure Code Warrior.