Versions Compared

Key

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

The static method doPrivileged is used to affirm that the invoking method is taking responsibility for exercising its own permissions 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 circumstances.

Noncompliant Code Example

There are two fallacies in this noncompliant code example. First, the doPrivileged method is being called from inside the openPasswordFile method. The openPasswordFile method is privileged and returns a FileInputStream reference to its caller. This allows any caller to call openPasswordFile() directly and obtain a reference to the sensitive file due to the inherent privileges possessed by the corresponding code. Second, the name of the sensitive password file is user controllable which introduces other risks such as unaccounted misuse of miscellaneous sensitive files.

Code Block
bgColor#FFcccc
public class Password { 
  public static void changePassword(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:\\" + 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)
 }	
}

Compliant Solution

The openPasswordFile method controls access to the sensitive password file and returns its reference. Because it cannot control being invoked by untrusted user methods, it should not assert its privileges within the body. Instead, changePassword() the caller method, can safely assert its own privilege whenever someone else calls it. This is because changePassword() does not return a reference to the sensitive file to any caller but processes the file internally. Also, because the name of the password file is hard-coded in the code, caller supplied (tainted) inputs are not used. Also, notice that the methods have been declared private in this case to limit scope.

...

Code Block
bgColor#ccccff
public static void readFont() throws FileNotFoundException {
  //Use own privilege to open the font file
  final String font_file = "fontfile";
  try {
    final InputStream in =
    AccessController.doPrivileged(new PrivilegedExceptionAction<InputStream>() {
				  
     public InputStream run() throws FileNotFoundException {
       return openFontFile(font_file); //call the privileged method here
     }
    });
    //Perform other operations 
  } catch (PrivilegedActionException exc) {				
      Exception cause = exc.getException();
      if (cause instanceof FileNotFoundException) {
        throw (FileNotFoundException)cause;
      } else { throw new Error("Unexpected exception type",cause); }
    }			
}

Risk Assessment

Invoking doPrivileged with too large a scope may allow an attacker to perform unintended operations with elevated privilege.

Rule

Severity

Likelihood

Remediation Cost

Priority

Level

SEC01-J

medium

probable

high

P4

L3

Automated Detection

TODO

Related Vulnerabilities

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

References

Wiki Markup
\[[API 06|AA. Java References#API 06]\] [method doPrivileged()|http://java.sun.com/javase/6/docs/api/java/security/AccessController.html#doPrivileged(java.security.PrivilegedAction)]
\[[Gong 03|AA. Java References#Gong 03]\] Sections 6.4, AccessController and 9.5 Privileged Code
\[[SCG 07|AA. Java References#SCG 07]\] Guideline 6-1 Safely invoke java.security.AccessController.doPrivileged
\[[MITRE 09|AA. Java References#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" 

...