In Java SE 6 and later, privileged code must either uses use the AccessController
mechanism or must be signed by an owner (or provider) who is trusted by whom the user trusts. Attackers could link privileged code with malicious code if the privileged code directly or indirectly invokes code from another package. In fact, a trusted jar file often contains code that is not privileged, but Trusted JAR files often contain code that requires no elevated privileges itself but that depends on privileged code; such code , this is known as security-sensitive code. If an attacker can link security-sensitive code with malicious code, they he or she can indirectly cause incorrect behavior with sensitive data. This exploit is called a mix-and-match attack.
Execution Normally, execution of untrusted code causes loss of privileges; the Java security model rescinds privileges . If when a trusted method invokes an untrusted one. When trusted code calls some untrusted code that attempts to perform some action requiring permissions not granted withheld by the security policy, the action is not allowedJava security model disallows that action. However, privileged code may use a class that exists in an untrusted container , performing and performs only unprivileged operations. If the attacker replaces this class were to replace the class in the untrusted container with a malicious implementationclass, the trusted code will retrieve might receive incorrect results .and misbehave at the discretion of the malicious code.
According to the Java SE Documentation, "Extension Mechanism Architecture" [EMA 2014]: According to the Java API \[[JarSpec 2008|AA. Bibliography#JarSpec 08]\], {{JAR}} file specification Wiki Markup
A package sealed within a JAR specifies that all classes defined in that package must originate from the same JAR. Otherwise, a
SecurityException
is thrown.
Sealing a JAR file automatically enforces the requirement of keeping privileged code together. In addition, it is important to adhere to rule OBJ15-J. Minimize minimize the accessibility of classes and their members.
Noncompliant Code Example (
...
Privileged Code)
This noncompliant code example uses includes a doPrivileged()
block and calls a method defined in a class that exists in a different, untrusted jar JAR file.:
Code Block | ||
---|---|---|
| ||
package trusted; import untrusted.RetValue; public class MixMatch { private void privilegedMethod() throws IOException { try { AccessController.doPrivileged( new PrivilegedExceptionAction<FileInputStream>PrivilegedExceptionAction<Void>() { public FileInputStreamVoid run() throws IOException, FileNotFoundException { final FileInputStream fis = new FileInputStream("file.txt"); try { RetValue rt = new RetValue(); if (rt.getValue() == 1) { // doDo something with sensitive file } } finally { fis.close(); } return null; // Nothing to return } } ); } catch (PrivilegedActionException e) { // forwardForward to handler and log } } public static void main(String[] args) throws IOException { MixMatch mm = new MixMatch(); mm.privilegedMethod(); } } // In another jarJAR file: package untrusted; class RetValue { public int getValue() { return 1; } } |
An attacker can provide an implementation of class RetValue
so that the privileged code uses the wrong an incorrect return value. Even if though class MixMatch
consists only of trusted, signed code, an attacker can still cause this behavior by maliciously deploying a legally valid signed jar JAR file containing the untrusted RetValue
class.
This example almost violates SEC01-J. Do not allow tainted variables in privileged blocks but does not do so. It instead allows potentially tainted code in its doPrivileged()
block, which is a similar issue.
Noncompliant Code Example (
...
Security-
...
Sensitive Code)
This noncompliant code example improves upon on the previous one example by moving usage the use of the RetValue
class outside the doPrivileged()
block.:
Code Block | ||
---|---|---|
| ||
package trusted; import untrusted.RetValue; public class MixMatch { private void privilegedMethod() throws IOException { try { final FileInputStream fis = AccessController.doPrivileged( new PrivilegedExceptionAction<FileInputStream>() { public FileInputStream run() throws FileNotFoundException { return new FileInputStream("file.txt"); } } ); try { RetValue rt = new RetValue(); if (rt.getValue() == 1) { // doDo something with sensitive file } } finally { fis.close(); } } catch (PrivilegedActionException e) { // forwardForward to handler and log } } public static void main(String[] args) throws IOException { MixMatch mm = new MixMatch(); mm.privilegedMethod(); } } // In another jarJAR file: package untrusted; class RetValue { public int getValue() { return 1; } } |
While Although the RetValue
class is not used within only outside the doPrivileged()
block, the behavior of RetValue.getValue()
certainly affects the behavior of security-sensitive code; that is, the code that operates on the file opened within the doPrivileged()
block. So Consequently, an attacker can still exploit the security-sensitive code with a malicious implementation of RetValue
.
Compliant Solution
This compliant solution combines all security-sensitive code into the same package an dthe and the same jar JAR file. It also reduces the accessibility of the getValue()
method to package-private. Sealing the package is necessary to prevent attackers from inserting any rogue classes.
Code Block | ||
---|---|---|
| ||
package trusted; public class MixMatch { // ... } // In the same signed & sealed jarJAR file: package trusted; class RetValue { int getValue() { return 1; } } |
To seal a package, use the sealed
attribute in the JAR file's manifest file header. This is shown below., as follows:
Code Block |
---|
Name: trusted/ // packagePackage name Sealed: true // sealedSealed attribute |
Exception
ENV01-J-EX0: Independent groups of privileged code and associated security-sensitive code (a "group" hereafter) may be placed in separate sealed packages . The enabling condition is that the and even in separate JAR files, subject to the following enabling conditions:
- The code in any one of these
...
- independent groups must lack any dynamic or static dependency on any of the code in any of the other
...
- groups. This means that code from one such
...
- group cannot invoke code from any of the others, whether directly or transitively.
- All code from any single group is contained within one or more sealed packages.
- All code from any single group is contained within a single signed JAR file.
Risk Assessment
Failure to place all privileged code together in one package and seal the package can lead to mix-and-match attacks.
Rule | Severity | Likelihood | Remediation Cost | Priority | Level |
---|---|---|---|---|---|
ENV01-J |
High |
Probable |
Medium | P12 | L1 |
Automated Detection
Detecting code that should be considered privileged or sensitive requires programmer assistance. Given identified privileged code as a starting point, automated tools could compute the closure of all code that can be invoked from that point. Such a tool could plausibly determine whether all code in that closure exists within a single package. A further check of whether the package is sealed appears feasible.
Related Vulnerabilities
is feasible.
Tool | Version | Checker | Description | ||||||
---|---|---|---|---|---|---|---|---|---|
CodeSonar |
| JAVA.INSEC.LDAP.POISON | Potential LDAP Poisoning (Java) |
Android Implementation Details
java.security.AccessController
exists on Android for compatibility purposes only, and it should not be usedSearch for vulnerabilities resulting from the violation of this rule on the CERT website.
Related Guidelines
...
...
, Acceptance of Extraneous Untrusted Data |
...
with Trusted Data |
Bibliography
...
[EMA 2014] | Extension Mechanism Architecture, "Optional Package Sealing" |
Rule 7, If you must sign your code, put it all in one archive file | |
...
\[[API 2006|AA. Bibliography#API 06]\]
\[[McGraw 1999|AA. Bibliography#Ware 99]\] Rule 7: If You Must Sign Your Code, Put It All in One Archive File (sic)
\[[Ware 2008|AA. Bibliography#Ware 08]\]