The static method java.security.AccessController.doPrivileged()
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 could 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 password.
...
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 the sensitive file because of the inherent privileges possessed by openPasswordFile
's doPrivileged()
block.
Code Block | ||
---|---|---|
| ||
public class Password { public static void changePassword(final String password_file) throws FileNotFoundException { FileInputStream fin; fin = openPasswordFile(password_file); } public static FileInputStream openPasswordFile(String password_file) throws FileNotFoundException { // 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 file } return null; // Still mandatory to return from run() } }); return f[0]; // Returns a reference to privileged objects (inappropriate) } } |
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. Both of the following compliant solutions avoid exposing any reference to the privileged data.
...
In summary, if the code can throw a checked exception without leaking sensitive information, prefer the form of doPrivileged()
method that takes a PrivilegedExceptionAction
instead of a PrivilegedAction
.
...
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.
...
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
...
SCG 2007 Guideline 6-1. Safely invoke java.security.AccessController.doPrivileged()
MITRE CWE: CWE-266 "Incorrect Privilege Assignment"
...