Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

The static method java.security.AccessController class is part of Java's security mechanism; it is responsible for enforcing the applicable security policy. doPrivilegedThis class's static doPrivileged() method executes a code block with a relaxed security policy. The doPrivileged() method stops permissions from being checked further down the call chain.

Consequently, any method that invokes doPrivileged() must assume affirms that the invoking method assumes responsibility for enforcing its own privileges and that the access permissions of its callers should be ignored. For example, an application may have permissions to operate on a sensitive file, however, a caller of the application may be allowed to operate with only the basic permissions. Invoking doPrivileged() in this context allows the application operating with basic permissions to use the sensitive file, for instance, when a user password change request requires an unprivileged application to use a more privileged application to set the new passwordsecurity on the code block supplied to doPrivileged(). Likewise, code in the doPrivileged() method must not leak sensitive information or capabilities.

For example, suppose that a web application must maintain a sensitive password file for a web service and also must run untrusted code. The application could then enforce a security policy preventing the majority of its own code—as well as all untrusted code—from accessing the sensitive file. Because it must also provide mechanisms for adding and changing passwords, it can call the doPrivileged() method to temporarily allow untrusted code to access the sensitive file. In this case, any privileged block must prevent all information about passwords from being accessible to untrusted code.

Noncompliant Code Example

In this noncompliant code example, the doPrivileged() method is called from the openPasswordFile() method. The openPasswordFile() method is privileged and returns a FileInputStream reference to its caller. This allows an untrusted caller to call openPasswordFile() directly and obtain a reference to for the sensitive password file because of the inherent privileges possessed by openPasswordFile's doPrivileged block. Because the method is public, it could be invoked by an untrusted caller.

Code Block
bgColor#FFcccc

public class PasswordPasswordManager {

  public static void changePassword(final String password_file) 
    throws FileNotFoundException {
    FileInputStream fin;
    fin = openPasswordFile(password_file);
 
 }

  public static// FileInputStreamTest openPasswordFile(Stringold password_file) 
with password in file throwscontents; FileNotFoundExceptionchange {password,
    // Declarethen asclose finalthe andpassword assignfile
 before the}

 body ofpublic thestatic anonymous inner class
FileInputStream openPasswordFile()
     // Arraythrows f[] is used to maintain language semantics while using finalFileNotFoundException {
    final String password_file = "password";
    final FileInputStream f[]fin = {null};
    //try Use{
 own privilege to open the sensitivefin password file
= AccessController.doPrivileged(
     AccessController.doPrivileged(   new PrivilegedActionPrivilegedExceptionAction<FileInputStream>() {
          public ObjectFileInputStream run() throws FileNotFoundException {
            // Sensitive action; can't be done outside tryprivileged {block
          f[0]   FileInputStream in = new FileInputStream(password_file);	// Perform privileged action

            return } catch(FileNotFoundException cnf) {
in;
          }
   // cannot recover if});
 password file is not} found;catch log(PrivilegedActionException tox) file{
      Exception cause  }= x.getException();
      if (cause returninstanceof null;FileNotFoundException) {
   // Still mandatory to return fromthrow run(FileNotFoundException) cause;
      } else {
        throw new Error("Unexpected exception type", }cause); 
     return f[0]; }
  // Returns a}
 reference to privileged objects (inappropriate)
return fin;
  }
}

Compliant Solution

In general, when any method containing the doPrivileged a privileged block exposes a field (such as a an object reference) beyond its own boundary, it becomes trivial for untrusted callers to exploit the program. Both compliant solutions (below) avoid exposing any reference to the privileged data.

Compliant Solution (Logging Exceptions)

The This compliant solution mitigates the vulnerability by declaring openPasswordFile() method controls access to the sensitive password file and returns its reference. For this reason, it should not be directly invokable. Instead, the changePassword() method must be used to forward any requests to openPasswordFile(). This is because changePassword() does not return a reference to the sensitive file to any caller and processes the file internally. Observe that caller supplied (tainted) inputs are not used because the name of the password file is hard-coded.

This compliant solution logs exceptions to a privileged log file. This choice is appropriate when data attached to the exception could potentially leak privileged information (e.g. the path to a privileged file).

be private. Consequently, an untrusted caller can call changePassword() but cannot directly invoke the openPasswordFile() method.

Code Block
bgColor#ccccff

public class PasswordPasswordManager {
  privatepublic static void changePassword() throws FileNotFoundException {
    // Use...
 own privilege}

 to openprivate thestatic sensitiveFileInputStream passwordopenPasswordFile() file
    final Stringthrows password_file = "password";FileNotFoundException {
    // ...
  }
}

Compliant Solution (Hiding Exceptions)

The previous noncompliant code example and the previous compliant solution throw a FileNotFoundException when the password file is missing. If the existence of the password file is itself considered sensitive information, this exception also must be prevented from leaking outside the trusted code.

This compliant solution suppresses the exception, leaving the array to contain a single null value to indicate that the file does not exist. It uses the simpler PrivilegedAction class rather than PrivilegedExceptionAction to prevent exceptions from propagating out of the doPrivileged() block. The Void return type is recommended for privileged actions that do not return any value.

Code Block
bgColor#ccccff
class PasswordManager {

  public static void changePasswordfinal FileInputStream f[] = {null};
    AccessController.doPrivileged(new PrivilegedAction() {
      public Object run() {
        try {
          f[0] FileInputStream fin = openPasswordFile(password_file);  // call the privileged method here
    if (fin   } catch(FileNotFoundException cnf== null) {
          // cannot recoverNo if password file is not found; loghandle to fileerror
        }

    // Test old password returnwith null;
password in     }
    });
    // Perform other operations such as old password verificationfile contents; change password
  }

  private static FileInputStream openPasswordFile(String password_file) throws FileNotFoundException {
    final FileInputStreamString fpassword_file = new FileInputStream(password_file)"password";
    //final Perform read/write operations on password fileFileInputStream fin[] = { null };
    return f;
  }
}

Compliant Solution (Throwing Wrapped Exceptions)

The previous compliant solution logs the exception instead of revealing sensitive information. (See guideline EXC06-J. Do not allow exceptions to transmit sensitive information for more information.) When none of the possible exceptions reveals sensitive information, we can use an equivalent mechanism that allows exceptions to be wrapped thus providing better diagnostic information for the caller. For example, an applet that lacks read-access to system files that contain fonts can accomplish the task from a privileged block without revealing any sensitive information. When non-sensitive exceptions provide more information, the client is better able to recognize the symptoms of a read failure.

Code Block
bgColor#ccccff

public static void readFont() throws FileNotFoundException {
  // Use own privilege to open the font file
  final String font_file = "fontfile";
AccessController.doPrivileged(new PrivilegedAction<Void>() {
        public Void run() {
          try {
    final InputStream in =
    AccessController.doPrivileged(new PrivilegedExceptionAction<InputStream>() {

     public InputStream run() throws FileNotFoundException {
 // Sensitive action; can't be done outside
            return// openFontFiledoPrivileged(font_file); // call the privileged method here
) block
           }
 fin[0] = new }FileInputStream(password_file);
     // Perform other operations
  } catch (PrivilegedActionExceptionFileNotFoundException excx) {
       Exception cause = exc.getException();     // Report to handler
      if (cause instanceof FileNotFoundException) {}
        throw (FileNotFoundException)cause  return null;
        }
  else { throw});
 new Error("Unexpected exception type", cause); }return fin[0];
    }
}

...

Risk Assessment

Returning references to sensitive resources from within a doPrivileged() block can break encapsulation and confinement and can leak capabilities. Any caller who can invoke the privileged code directly and obtain a reference to a sensitive resource or field can maliciously modify its elements.

Guideline Rule

Severity

Likelihood

Remediation Cost

Priority

Level

SEC02SEC00-J

medium Medium

likely Likely

high High

P6

L2

Automated Detection

Identifying sensitive information requires assistance from the programmer; fully - automated identification of sensitive information is beyond the current state of the art.

If we had Assuming user-provided tagging of sensitive information, we could do some kind of escape analysis could be performed on the doPrivileged() blocks and perhaps to prove that nothing sensitive leaks out of from them. We could even use something akin to thread coloring Methods similar to those used in thread-role analysis could be used to identify the methods that either must (, or must not) , be called from doPrivileged() blocks.

Related

...

Search for vulnerabilities resulting from the violation of this guideline on the CERT website.

Bibliography

Guidelines

MITRE CWE

CWE-266, Incorrect Privilege Assignment
CWE-272, Least Privilege Violation

Secure Coding Guidelines for Java SE, Version 5.0

Guideline 9-3 / ACCESS-3: Safely invoke java.security.AccessController.doPrivileged

Android Implementation Details

The java.security package exists on Android for compatibility purposes only, and it should not be used.

Bibliography

[API 2014]

Method doPrivileged()

[Gong 2003]

Section 6.4, "AccessController"
Section 9.5, "Privileged Code"

 

...

Image Added Image Added Image Added

Wiki Markup
\[[API 2006|AA. Bibliography#API 06]\] [method doPrivileged()|http://java.sun.com/javase/6/docs/api/java/security/AccessController.html#doPrivileged(java.security.PrivilegedAction)]
\[[Gong 2003|AA. Bibliography#Gong 03]\] Sections 6.4, AccessController and 9.5 Privileged Code
\[[SCG 2007|AA. Bibliography#SCG 07]\] Guideline 6-1 Safely invoke java.security.AccessController.doPrivileged
\[[MITRE 2009|AA. Bibliography#MITRE 09]\] [CWE ID 266|http://cwe.mitre.org/data/definitions/266.html] "Incorrect Privilege Assignment", [CWE ID 272|http://cwe.mitre.org/data/definitions/272.html] "Least Privilege Violation"

SEC01-J. Minimize the accessibility of classes and their members      02. Platform Security (SEC)      SEC03-J. Do not allow tainted variables in doPrivileged blocks