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.

Using these methods inside the doPrivileged block stops any security manager checks from being applied to callers further up the execution stack. Therefore, the methods below should not be used in a doPrivileged block:
Copy
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.

Copy
 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
             }
         });
     }
 }
Copy
  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.

Copy
 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

Copy
 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

Copy
 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:

Copy
 AccessController.doPrivileged((PrivilegedAction) () -> {
     field.setAccessible(true);  // <----- SV.PRIVILEGE.MISSING should not be in doPrivileged block
     return null;
 });

Fixed code example 2

Copy
 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

Security training

Application security training materials provided by Secure Code Warrior.