According to the principle of least privilege, code should not be granted more privileges than those required for performing a task. This means that sections of code that require elevated privileges should be kept to a minimum. McGraw and Felten [[McGraw 00]] enlist various goals of the principle of least privilege in the context of the Java programming language:
- We want to grant each applet or application the minimum privileges it needs.
- Rather than assigning a given applet's entire collection of privileges to all of its classes, we want each class to get just what it needs.
- We want a class's privileges to be "turned off" except for brief periods of time.
- We even want to reduce the privileges of some of the built-in system classes.
The ways in which these goals can be achieved are discussed below.
Granting an applet the minimum privileges it needs is achieved by not signing it when it performs only unprivileged operations (ENV00-J. Do not sign code that performs only unprivileged operations). For applications, some additional steps may be required depending on the security policy. The default security policy file is restrictive. However, the security model allows the user to grant additional permissions to applications by using a custom security policy. Several guidelines deal with granting or suppressing permissions (for instance, ENV00-J. Do not sign code that performs only unprivileged operations, ENV31-J. Never grant AllPermission to untrusted code, ENV32-J. Do not grant ReflectPermission with target suppressAccessChecks and ENV33-J. Do not grant RuntimePermission with target createClassLoader).
There are several ways to practice privilege separation. Applets or applications that need to be signed can coexist with unsigned classes in the same package (or JAR file). Furthermore, it is possible to grant privileges to code on the basis of the code base or its signer.
The third goal is realized by using the AccessController mechanism. Only certain parts of code require elevated privileges and this mechanism allows just that. When a class needs to enable its own privileges, it calls the sensitive methods in a doPrivileged block. It is critical that these privileges be revoked as soon as the sensitive operations have concluded. Users most often do not understand complex security policies nor do they understand code signing. They cannot be relied upon to restrict permissions in non-default policy files. Consequently, privileged code must be written with utmost care assuming that the user is incapable of correctly configuring the security policy.
The fourth goal can be achieved, in part, by granting code specific permissions and protecting it from accessing classes in certain packages. This can be achieved by using the accessClassInPackage permission (SEC07-J. Do not grant untrusted code access to classes existing in forbidden packages). Doing so does not limit what system classes can do, however, it restricts the range of system packages that can be invoked from less-privileged code.
Noncompliant Code Example
This noncompliant example includes nonprivileged code following the privileged openPasswordFile statement in a doPrivileged block. This is a violation of the principle of least privilege.
AccessController.doPrivileged(new PrivilegedAction() {
public Object run() {
try {
f[0] = openPasswordFile(password_file); // call the privileged method here
// other operations
}catch(FileNotFoundException cnf) {
System.err.println("Error: Operation could not be performed");
}
return null;
}
});
Compliant Solution
It is critical to restrict the code that requires elevated privileges to a minimum. Privileged code must also be audited more carefully than non-privilege code to ensure than there are no other security vulnerabilities. This is essential to prevent the misuse of privileges.
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;
}
});
// other operations
Risk Assessment
Failure to follow the principle of least privilege can lead to privilege escalation attacks when a vulnerability is exploited.
Rule |
Severity |
Likelihood |
Remediation Cost |
Priority |
Level |
|---|---|---|---|---|---|
SEC00- J |
high |
probable |
high |
P6 |
L2 |
Automated Detection
TODO
Related Vulnerabilities
Search for vulnerabilities resulting from the violation of this rule on the CERT website.
References
[[McGraw]]
[[MITRE 09]] CWE 272![]()
02. Platform Security (SEC) 02. Platform Security (SEC) SEC01-J. Provide sensitive mutable classes with unmodifiable wrappers