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

Compare with Current View Page History

« Previous Version 87 Next »

Sometimes code needs to take into account the privileges of another context while performing a security critical action. Granting such code all of the privileges of the current execution context (snapshot of the current thread) can expose a vulnerability. Ideally, code should only be granted the privileges it needs to complete its operation, with no excess privileges allowed.  This adds extra complexity to privileged code, and often the cost (in terms of complexity and maintainability) for carefully restricting privileges must be weighed against the additional security granted, when deciding how much  restriction of privileges is necessary.

Noncompliant Code Example

This noncompliant code example shows a library method that allows callers to perform a privileged operation (such as a read or write to a file), using the wrapper method performActionOnFile().

private FileInputStream openFile() {
  final FileInputStream f[] = {null};
 
  AccessController.doPrivileged(new PrivilegedAction() {
    public Object run() {
      try {
        f[0] = new FileInputStream("file"); 
      } catch(FileNotFoundException fnf) { 
        // Forward to handler
      }
      return null;
    }
  });
  return f[0];
}

// wrapper method
public void performActionOnFile() {
  openFile();	
}

The security policy that applies to this code may grant the permissions to both read and write to the file. However, the caller only requires read access to the file. Consequently, this code violates the principle of least privilege by also providing the caller with superfluous write access.

Compliant Solution

The two-argument form of doPrivileged() accepts an AccessControlContext object from the caller and restricts the privileges of the contained code to the intersection of the permissions of the current execution context's domains and those of the context passed as the second argument. Consequently, a caller that requires only read permission to the file can pass a context that has only the file read permission. 

An AccessControlContext that grants the file read permission can be created as an inner class.

 

private FileInputStream openFile(AccessControlContext context) {
  if (context == null) {
    throw new SecurityException("Missing AccessControlContext");
  }

  final FileInputStream f[] = { null };
  AccessController.doPrivileged(new PrivilegedAction() {
    public Object run() {
      try {
        f[0] = new FileInputStream("file");
      } catch (FileNotFoundException fnf) {
        // Forward to handler
      }
      return null;
    }
  }, context); // Restrict the privileges by passing the context argument
  return f[0];
}

 
private static class FileAccessControlContext {
  public static final AccessControlContext INSTANCE;
  static {
    Permission perm = new java.io.FilePermission("file", "read");
    PermissionCollection perms = perm.newPermissionCollection();
    perms.add(perm);
    INSTANCE = new AccessControlContext(new ProtectionDomain[] {
      new ProtectionDomain(null, perms)});
  }
}


// Wrapper method
public void performActionOnFile() {
  openFile(FileAccessControlContext.INSTANCE); // only grant open-for-reading perms, see below
}

Alternatively, an appropriate AccessControlContext can be obtained using AccessController.getContext() if the caller does not have privileges to create it.

In this example, the two-argument form is preferable because the openFile() method does not know whether the caller should be granted read, write, or both permissions. In the special case where all the callers are known (for example, when all are private methods of a private class), the single argument method AccessController.checkPermission(permission) offers improved simplicity and performance. The two argument form should be used for all cases where there may be unknown callers. The performActionOnFile() method does not need to be declared private, provided permissions are restricted by accepting a context argument.

Applicability

Failure to follow the principle of least privilege can lead to abuse of the excess privileges that were granted.

Related Guidelines

MITRE CWECWE ID 272, "Least Privilege Violation"

Bibliography

[API 2011] Class AccessController


  • No labels