You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 31 Next »

Sensitive operations must be protected by security manager checks. Refer to guideline ENV02-J. Create a secure sandbox using a Security Manager to learn about the importance of performing security checks and limiting code to a secure sandbox.

Noncompliant Code Example

This noncompliant code example instantiates a Hashtable and defines a removeEntry() method to allow the removal of its entries. However, the method is public and non-final, which leaves it susceptible to malicious callers.

class SensitiveHash {
  Hashtable<Integer,String> ht = new Hashtable<Integer,String>();

  public void removeEntry(Object key) {
    ht.remove(key);
  }
}

Compliant Solution

This compliant solution installs a security check to protect entries from being maliciously removed from the Hashtable instance. A SecurityException is thrown if the caller does not possess the java.security.SecurityPermission removeKeyPermission.

class SensitiveHash {
  Hashtable<Integer,String> ht = new Hashtable<Integer,String>();

  void removeEntry(Object key) {
    check("removeKeyPermission");
    ht.remove(key);
  }

  private void check(String directive) {
    SecurityManager sm = System.getSecurityManager();
      if (sm != null) {
        sm.checkSecurityAccess(directive);
      }
  }
}

The SecurityManager.checkSecurityAccess() method determines whether the action controlled by the particular permission is allowed.

Noncompliant Code Example

This noncompliant code example uses the SecurityManager.checkRead() method to check whether the file schema.dtd can be read from the file system. The check*() methods lack support for fine grained access control. For example, the check*() methods are insufficient to enforce a policy permitting read access to all files with the dtd extension and forbidding read access to all other files. New code should rarely use the check*() methods because the default implementations of the Java libraries already use these methods to protect sensitive operations.

SecurityManager sm = System.getSecurityManager();

if (sm != null) {  // check whether file may be read
  sm.checkRead("/local/schema.dtd");
}

Compliant Solution

J2SE 1.2 added two methods—checkPermission(Permission perm) and {{checkPermission(Permission perm, Object context)}}—to the SecurityManager class. The motivations for this change included

  • Eliminating the necessity to hardcode names of checks in method names.
  • Encapsulating the complicated algorithms and code for examining the Java runtime in a single checkPermission() method.
  • Supporting introduction of additional permissions by subclassing the Permission class.

The single argument checkPermission() method uses the context of the currently executing thread environment to perform the checks. If the context has the permissions defined in the local policy file, the check succeeds; otherwise, a SecurityException is thrown.

This compliant solution shows the single argument checkPermission() method and allows files in the local directory with the dtd extension to be read. DTDPermission is a custom permission that enforces this level of access. (See guideline SEC10-J. Define custom security permissions for fine grained security for details on creating custom permissions). Even if the java.io.FilePermission is granted to the application with the action "read", DTD files will be subject to additional access control.

SecurityManager sm = System.getSecurityManager();

if(sm != null) {  //check if file can be read
  DTDPermission perm = new DTDPermission("/local/",  "readDTD");
  sm.checkPermission(perm);
}

Sometimes the security check code exists in one context (such as a worker thread) while the check has to be conducted on a different context, like another thread. The two argument checkPermission() method is used in this case. It accepts an AccessControlContext instance as the context argument. The effective permissions are not computed as the intersection of the permissions of the two contexts and consist of the permissions of the context argument only.

Both the single and double argument checkPermission() methods defer to the single argument java.security.AccessController.checkPermission(Permission perm) method. When invoked directly, this method operates only on the current execution context and, as a result, does not supersede the security manager's two argument version.

A cleaner approach to making a security check from a different context is to take a snapshot of the execution context in which the check must be performed, using the java.security.AccessController.getContext() method that returns an AccessControlContext object. The AccessControlContext class itself defines a checkPermission() method that encapsulates a context, instead of accepting the current executing context as a parameter. This allows the check to be performed at a later time, as shown in the following example.

// Take the snapshot of the required context, store in acc and pass it to another context
AccessControlContext acc = AccessController.getContext();

// Accept acc in another context and invoke checkPermission() on it
acc.checkPermission(perm);

Risk Assessment

Failing to enforce security checks in code that performs sensitive operations can lead to malicious tampering of sensitive data.

Guideline

Severity

Likelihood

Remediation Cost

Priority

Level

SEC08-J

high

probable

medium

P12

L1

Automated Detection

Identifying sensitive operations requires assistance from the programmer; fully-automated identification of sensitive operations is beyond the current state of the art.

Given knowledge of which operations are sensitive, as well as which security checks must be enforced for those operations, an automated tool could reasonably enforce the invariant that the sensitive operations are invoked only from contexts where the security checks have been performed.

Related Vulnerabilities

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

Bibliography

[[API 2006]]


SEC07-J. Classes that derive from a sensitive class or implement a sensitive interface must be declared final      14. Platform Security (SEC)      SEC09-J. Do not base security checks on untrusted sources

  • No labels