Versions Compared

Key

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

In Java SE 6 and Java SE 7later, privileged code must either use the AccessController mechanism or be signed by an owner (or provider) whom the user trusts. Attackers could link privileged code with malicious code if the privileged code directly or indirectly invokes code from another package. Trusted JAR files often contain code that requires no elevated privileges itself , but that depends on privileged code; such code is known as security-sensitive code. If an attacker can link security-sensitive code with malicious code, he or she can indirectly cause incorrect behavior. This exploit is called a mix-and-match attack.

Normally, execution of untrusted code causes loss of privileges; the Java security model rescinds priveleges privileges when a trusted method invokes an untrusted one. When trusted code calls untrusted code that attempts to perform some action requiring permissions withheld by the security policy, the Java security model disallows that action. However, privileged code may use a class that exists in an untrusted container and performs only unprivileged operations. If the attacker were to replace the class in the untrusted container with a malicious class, the trusted code might receive incorrect results and misbehave at the discretion of the malicious code.unmigrated-wiki-markup

According to the Java API \[[EMA 2011|AA. References#EMA 2011]\]Java SE Documentation, "Extension Mechanism Architecture" [EMA 2014]:

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.

...

This noncompliant code example includes a doPrivileged() block and calls a method defined in a class in a different, untrusted JAR file.:

Code Block
bgColor#FFcccc

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 fis;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 JAR file:
package untrusted;

class RetValue {
  public int getValue() {
    return 1;
  }
}

...

This example almost violates rule 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.

...

This noncompliant code example improves upon on the previous example by moving the use of the RetValue class outside the doPrivileged() block.:

Code Block
bgColor#FFcccc

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 JAR file:
package untrusted;

class RetValue {
  public int getValue() {
    return 1;
  }
}

Although the RetValue class is used only outside the doPrivileged() block, the behavior of RetValue.getValue() affects the behavior of security-sensitive code that operates on the file opened within the doPrivileged() block. Consequently, an attacker can still exploit the security-sensitive code with a malicious implementation of RetValue.

...

This compliant solution combines all security-sensitive code into the same package and the same 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
bgColor#ccccff

package trusted;

public class MixMatch {
  // ...
}


// In the same signed & sealed JAR 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, 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 and even in separate JAR files, subject to the following enabling conditions:

...

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

High

probable

Probable

medium

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 is feasible.

ToolVersionCheckerDescription
CodeSonar
Include Page
CodeSonar_V
CodeSonar_V

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 used.

Related Guidelines

MITRE CWE

CWE-349

.

, Acceptance of

extraneous untrusted data with trusted data

Bibliography

Extraneous Untrusted Data with Trusted Data

Bibliography

[EMA 2014]

Extension Mechanism Architecture, "Optional Package Sealing"

[McGraw 1999

<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="510233cb-a1dc-4e73-b5b6-5754025087e2"><ac:plain-text-body><![CDATA[

[[EMA 2011

AA. References#EMA 2011]]

Optional Package Sealing

]]></ac:plain-text-body></ac:structured-macro>

<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="d6fe0bfe-9bf1-4df4-bf46-d0f36e135022"><ac:plain-text-body><![CDATA[

[[McGraw 1999

AA. References#Ware 99]

]

Rule 7, If you must sign your code, put it all in one archive file

]]></ac:plain-text-body></ac:structured-macro>

<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="9532023d-01da-4a40-8a54-edeaa7444dfd"><ac:plain-text-body><!

[

CDATA[[[

Ware 2008

AA. References#Ware 08]]

 

]]></ac:plain-text-body></ac:structured-macro>

]



...

Image Added Image Added Image Removed      15. Runtime Environment (ENV)