...
Consequently, any method that contains a doPrivileged()
method call must assume responsibility for enforcing its own security on the code block supplied to doPrivileged()
. Likewise any code in the {[doPrivileged()
}} method must take care to prevent sensitive information from leaking out of a trust boundary. This may indicate that said information must not escape from the doPrivileged()
block itself, or it may be permitted within part of the application and excluded from other parts.
For example, suppose that a web application must maintain a sensitive file of passwords for a web service, and further that it must also run untrusted code. The application could then enforce a security policy preventing the majority of its own code, and all untrusted code, from accessing the sensitive file. Because it must also provide mechanisms for adding and changing passwords, it can use the doPrivileged()
method to temporarily bypass its own security policy for the purpose of managing passwords. In this case, any privileged block must prevent any information about passwords from being accessible to untrusted code.
...
This compliant solution mitigates the vulnerability by declaring openPasswordFile()
to be private. Consequently, an untrusted caller can call changePassword()
but cannot directly invoke the openPasswordFile()
method.
Code Block | ||
---|---|---|
| ||
public class PasswordManager { public static void changePassword() throws FileNotFoundException { // ... } private static FileInputStream openPasswordFile() throws FileNotFoundException { // ... } } |
...
Both the previous noncompliant code example and the previous compliant solution would throw a FileNotFoundException
when the password file is missing. But suppose that If the existence of the password file is itself considered sensitive information, and should this exception must also not be revealed to potentially untrusted code?allowed to leak outside the trust boundary.
This compliant solution suppresses the exception, using a null return 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.
...
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 prove that nothing sensitive leaks out of 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.
...
<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="c27abbca2f4340ab-48cbc928-4666411d-982997f2-c91d6896e15e2ed0d92293d5"><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="39cae231a0ac366c-8f3ecbcd-4a6e4e16-a812aae6-9f73edde659f061757f0bf13"><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> |
...