Versions Compared

Key

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

...

This rule concerns sensitive information escaping from a doPrivileged() block. For information about untrusted information entering a doPrivileged() block, see SEC03-J. Do not allow tainted variables in doPrivileged blocks.

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 for the sensitive password file to its caller. Since the method is public, it could be invoked by an untrusted caller.

Code Block
bgColor#FFcccc
public class Password {
  public static void changePassword() throws FileNotFoundException {
    FileInputStream fin = openPasswordFile(password_file);

    // test old password with password in file contents; change password
  }

  public static FileInputStream openPasswordFile() {
    final String password_file = "password";

    // Declare as final and assign before the body of the anonymous inner class
    // Array f[] is used to maintain language semantics while using final
    final FileInputStream f[] = {null};
    // Use own privilege to open the sensitive password file
    AccessController.doPrivileged(new PrivilegedAction() {
      public Object run() {
        try {
          f[0] = new FileInputStream(password_file);	// Perform privileged action
        } catch (FileNotFoundException cnf) {
          // cannot recover if password file is not found; log to sensitive file
        }
        return null;    // Still mandatory to return from run()
      }
    });
   return f[0];  // Returns a reference to privileged objects (inappropriate)
 }
}

Compliant Solution (Logging Exceptions)

In general, when any method containing the doPrivileged() block exposes a field (such as a reference) beyond its own boundary, it becomes trivial for untrusted callers to exploit the program.

...

Code Block
bgColor#ccccff
class Password {
  public static void changePassword() {
    // ...
  }

  private static FileInputStream openPasswordFile() {
    // ...
  }
}

Compliant Solution (Throwing Wrapped Exceptions)

The previous compliant solution logs the exception instead of letting a FileNotFoundException propagate to a caller, in compliance with rule EXC06-J. Do not allow exceptions to transmit sensitive information.

...

In summary, if the code can throw a checked exception without leaking sensitive information, then use the form of doPrivileged() method that takes a PrivilegedExceptionAction instead of a PrivilegedAction.

Risk Assessment

Returning references to sensitive resources from within a doPrivileged() block can break encapsulation and confinement. 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

Severity

Likelihood

Remediation Cost

Priority

Level

SEC02-J

medium

likely

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 user-provided tagging of sensitive information, we could do some kind of escape analysis on the doPrivileged() blocks and perhaps prove that nothing sensitive leaks out of them. We could even use something akin to thread coloring to identify the methods that either must (or must not) be called from doPrivileged() blocks.

Related Vulnerabilities

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

Related Guidelines

SCG 2007

Guideline 6-1. Safely invoke java.security.AccessController.doPrivileged()

MITRE CWE

CWE-266 "Incorrect Privilege Assignment"

 

CWE-272 "Least Privilege Violation"

Bibliography

<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="91988439f1955bc6-a873428e-4ad04593-b9df95fe-db4cfdb9f7b8e2b7b03e3378"><ac:plain-text-body><![CDATA[

[[API 2006

AA. Bibliography#API 06]]

[method doPrivileged()

http://java.sun.com/javase/6/docs/api/java/security/AccessController.html#doPrivileged(java.security.PrivilegedAction)]

]]></ac:plain-text-body></ac:structured-macro>

<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="eb23846aa92bedfd-9260de06-4e104e93-8f00832b-75758c32faf406f27180d161"><ac:plain-text-body><![CDATA[

[[Gong 2003

AA. Bibliography#Gong 03]]

Sections 6.4, AccessController and 9.5 Privileged Code

]]></ac:plain-text-body></ac:structured-macro>

...