Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: needs more rework

Wiki Markup
According to the Class {{SecurityManager}} documentationJava API \[[API 06|AA. Java References#API 06]\], class {{SecurityManager}} documentation:

The security manager is a class that allows applications to implement a security policy. It allows an application to determine, before performing a possibly unsafe or sensitive operation, what the operation is and whether it is being attempted in a security context that allows the operation to be performed. The application can allow or disallow the operation.

As an example, the applet security manager denies applets all but the most essential privileges. It is designed to protect inadvertent system modification, information leakage and user impersonation. The use of security managers is not limited to client side protection. Webservers such as Tomcat and Websphere use this facility to isolate trojan servlets, malicious JSP code and protect sensitive system resources from inadvertent access. For Java applications that run from the command line, a default or custom security manager can be set using a special flag described a little later. Alternatively, it is possible to install a security manager programatically.

From Java 2 SE Platform onwards, SecurityManager is a non-abstract class. As a result, there is no explicit requirement of overriding its methods. To create and use a security manager programatically, the code must have the runtime permissions createSecurityManager (to instantiate SecurityManager) and setSecurityManager to install it. These permissions are checked only if a security manager is already installed. This is useful for situations where there is a global-default security manager in place, such as on a virtual host, and individual hosts need to be denied the requisite permissions for overriding the default security manager with a custom one.

The security manager is closely related tied to the AccessController class. The former is used as a hub for access control whereas the latter is the actual implementer of a particular the access control algorithm. Two requirements necessitate the use of the security manager:

...

  • Defining custom policies: It is sometimes desired to subclass the security manager to define multilevel, coarse or fine grained security policies with system wide application.

Wiki Markup
TheRegarding the implementation and use of custom security managers, the Java Security Architecture Specification \[[SecuritySpec 08|AA. Java References#SecuritySpec 08]\] aptly paints the picture:

We encourage the use of AccessController in application code, while customization of a security manager (via subclassing) should be the last resort and should be done with extreme care. Moreover, a customized security manager, such as one that always checks the time of the day before invoking standard security checks, could and should utilize the algorithm provided by AccessController whenever appropriate.

Many of the Java SE APIs use security manager checks by default before performing sensitive operations. For example, the constructor of class java.io.FileInputStream throws a SecurityException if the caller does not have the permission to read a file. Installing a security manager from the command line or programatically helps create a default sandbox that denies such permissions if the security policy file in effect does not grant them.

Noncompliant Code Example

The worst form of non-compliance is not using the the security manager at allor the AccessController mechanism. Even when used, there can be cases where the appropriate checks are not installed. In the This noncompliant code example that follows, passes a null value is passed to the setSecurityManager method that is responsible for establishing a current setting the expected instance of SecurityManager. As a result, no security manager will be installed (assuming that the security manager is not installed from the command line either).

Code Block
bgColor#FFcccc
try {
  System.setSecurityManager(null);
} catch (SecurityException se) { System.out.println("SecurityManager is already set!"); 
  // cannot set security manager, log to file
}

Noncompliant Code Example

...

Code Block
bgColor#FFcccc
try {
  System.setSecurityManager(new CustomSecurityManager("password here"));
} catch (SecurityException se) { System.out.println("SecurityManager is already set!"); 
  // cannot set security manager, log to file
}

Compliant Solution

This compliant solution demonstrates how a custom SecurityManager class called CustomSecurityManager can be activated by invoking its constructor with a password. Various check* methods defined within the class can then be invoked to perform access checks. In this case, checkRead() succeeds if the current protection domain's file permission name tallies with that of the file name argument for the read action.

Code Block
bgColor#ccccff
try {
  System.setSecurityManager(new CustomSecurityManager("password here"));
  SecurityManager sm = System.getSecurityManager();
  if(sm != null) {  //check if file can be read
    sm.checkRead("/temp/tempFile");
  } 
} catch (SecurityException se) { System.out.println("Not allowed");  
  // cannot set security manager, log to file
}

Compliant Solution

An alternative is to use the default security manager instead of a custom one, as shown below. To do this, change the active instance to java.lang.SecurityManager (invoke setSecurityManager() with the argument new SecurityManager()).

Code Block
bgColor#ccccff
try {
  System.setSecurityManager(new SecurityManager());
  SecurityManager sm = System.getSecurityManager();

  if(sm != null) {  //check if file can be read
    sm.checkRead("/temp/tempFile");
  } 
} catch (SecurityException se) { System.out.println("Not allowed");  
  // cannot set security manager, log to file
}

Compliant Solution

The check*() methods detailed in the preceding compliant solutions were more prevalent in JDK versions 1.xolder Java SE versions. Two methods, checkPermission(Permission perm) and checkPermission(Permission perm, Object context) were added in J2SE 1.2. The motivations for this change were manifold -:

  • The checkPermission methods eliminated the need for hardcoding names of the checks in the call.
  • They used only one copy of the complicated algorithms and code for examining the Java runtime by using a common checkPermission method.
  • Newer permissions for resources could be easily added by encapsulating them in a new Permission class subclass.

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

...

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, such as another thread. The two argument checkPermission 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.

here, passing in the instance of an AccessControlContext as the context argument. 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 currently current execution context and as a result does not supersede the security manager's two argument version.

There is also , however, another (cleaner and preferable) way to handle the security check from a different context. This is accomplished by taking a snapshot of the currently executing current execution context 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 taking in accepting the currently current executing context as a parameter. This is shown below.

Code Block
bgColor#ccccff
// 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); // Check permissions in another context

Compliant Solution

Any Java program (bean, servlet or application) can instantiate a SecurityManager. However, for applications designed to run locally, an explicit flag must be set to enforce the SecurityManager policy whenever the security manager is not set programatically. Sometimes this is desired when the user operates using a custom security policy and does not want to rely on the vendor supplied security applications must not install custom security managers but only obey the default global policy. The default security manager at the user end can be installed using the flags as follows:

...

If it is known in advance that the user prefers using a custom the default security policymanager, the setSecurityManager() method in code can be forgone and substituted with just the getSecurityManager() method as the security manager is installed using the command line flag and need not be set aet explicitly. A custom security manager can be installed by adding the absolute path to the custom security manager, made the default and enforced globally by specifying its absolute path location immediately after an equal-to sign appended immediately that appears after the flag.

The default policy file java.policy grants a few permissions (reading system properties, binding to unprivileged ports and so forth) and can be found in the ~/java.home/lib/security directory on UNIX-like systems and its equivalent on Microsoft Windows systems. There is also a user specific policy file in the user's home directory. The union of both these policy files defines the permissions given to a program. Refer to the java.security file to set which policy files should be used. If either of these is deleted, by default no permissions are granted to the implementing code.

If the default policy file needs to be bypassed in lieu of a custom policy file, a the double equals (==) idiom should be used instead of the single equals =.

Code Block
bgColor#ccccff
java -Djava.security.manager -Djava.security.policy==policyURL LocalJavaApp

...