The static method doPrivileged
is used to affirm that the invoking method is taking responsibility for exercising enforcing its own permissions 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 this application may be allowed to operate with only basic user permissions. Invoking doPrivileged()
in the context of this method allows it to exercise its own (possibly elevated) permissions under such circumstancesthe application operating with only basic user permissions to operate on the sensitive file.
Noncompliant Code Example
In this noncompliant code example, the doPrivileged
method is called from within 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 due to because of the inherent privileges possessed by the corresponding code.
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}; final String file = password_file; //Use own privilege to open the sensitive password file AccessController.doPrivileged(new PrivilegedAction() { public Object run() { try { f[0] = new FileInputStream("c:\\" + passowrd_file); //Perform privileged action }catch(FileNotFoundException cnf) { System.err.println(cnf.getMessage()); } 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.
...
Code Block | ||
---|---|---|
| ||
class Password { private static void changePassword() { //Use own privilege to open the sensitive password file final String password_file = "password"; final FileInputStream f[] = {null}; AccessController.doPrivileged(new PrivilegedAction() { public Object run() { try { f[0] = openPasswordFile(password_file); //call the privileged method here }catch(FileNotFoundException cnf) { System.err.println("Error: Operation could not be performed"); } return null; } }); //Perform other operations such as password verification } private static FileInputStream openPasswordFile(String password_file) throws FileNotFoundException { FileInputStream f = new FileInputStream("c:\\" + password_file); //Perform read/write operations on password file return f; } } |
The above previous compliant solution prints a general error instead of revealing sensitive information (See EXC01-J. Do not allow exceptions to transmit sensitive information) . If and as a result, swallows all exceptions. Sometimes no sensitive information can be revealed by any of the possible exceptions. In such cases, an equivalent mechanism that allows exceptions to be wrapped can be used. This allows the caller to obtain better diagnostic information. For example, if an applet doesn't have access to read system files that contain fonts, it can accomplish the task from a privileged block without revealing any sensitive information. In fact, by not swallowing exceptions, the client will be able to can deduce the symptoms of a read failure quite easily.
...
In summary, if the code can throw a checked exception safely, use without leaking sensitive information, prefer the form of doPrivileged
method that takes a PrivilegedExceptionAction
instead of a PrivilegedAction
.
Risk Assessment
Invoking doPrivileged
with too large a scope may allow an attacker to perform unintended operations with elevated privilegeReturning references to sensitive resources from within a doPrivileged()
block can break encapsulation ad 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.
Rule | Severity | Likelihood | Remediation Cost | Priority | Level |
---|---|---|---|---|---|
SEC36-J | medium | likely | high | P6 | L2 |
...