...
As an example, the security manager denies applets all but the most essential privileges. It is designed to protect inadvertent system modification, information leakage and user impersonation. From Java 2 Platform onwards, SecurityManager
is a non-abstract class. As a result, there is no explicit requirement of overriding its methods. To use a security manager, the code must have the runtime permissions createSecurityManager
(to instantiate SecurityManager
and avoid certain information leakage) and setSecurityManager
to install it.
The security manager is closely related to the AccessController
. The former is used as a hub for access control whereas the latter is the implementer of a particular access control algorithm. Two requirements necessitate the use of the security manager -
- Providing backward compatibility: Legacy code often contains custom implementations of the security manager class since it was originally
abstract
.
- 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 |
---|
\[[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.
Noncompliant Code Example
...
Code Block | ||
---|---|---|
| ||
java application |
Compliant Solution
The SecurityManager
class was abstract
prior to Java 2, forcing the code to subclass it and define custom implementations. 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. Alternatively, to use the default security manager instead of a custom one, change the active instance to java.lang.SecurityManager
(invoke setSecurityManager()
with the argument new SecurityManager()
).
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 | ||
---|---|---|
| ||
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"); }
|
The method detailed in the preceding lines was more prevalent in JDK versions 1.x. 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 utilized 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.
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.
This compliant solution exemplifies the single argument checkPermission
method.
Code Block | ||
---|---|---|
| ||
try { System.setSecurityManager(new CustomSecurityManager("password here")); SecurityManager sm = System.getSecurityManager(); if(sm != null) { //check if file can be read FilePermission perm = new FilePermission("/temp/tempFile", "read"); sm.checkPermission(perm); } } catch (SecurityException se) { System.out.println("SecurityManager is already set!"); }Not allowed"); } |
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 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 execution context and thus 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 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 the currently executing context. This is shown below.
Code Block | ||
---|---|---|
| ||
// Take the snapshot of the required context
AccessControlContext acc = AccessController.getContext();
// ...
acc.checkPermission(perm); // Check permissions in another context
|
For local applications, the security manager can be installed using the flags as shown next. Note that the setSecurityManager
method must be replaced by getSecurityManager
in this case since the manager has already been installed using the command line flag.
Code Block | ||
---|---|---|
| ||
java -Djava.security.manager -Djava.security.policy=policyURL LocalJavaApp |
...
The default policy file java.policy
grants a few permissions (reading system properties, binding to unprivileged ports and so on) and can be found in the ~/java.home/lib/security
directory on *nix based 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.
...
Wiki Markup |
---|
\[[API 06|AA. Java References#API 06]\] [Class SecurityManager|http://java.sun.com/javase/6/docs/api/java/lang/SecurityManager.html], Class AccessControlContext, Class AccessController \[[Policy 02|AA. Java References#Policy 02]\] \[[Pistoia 04|AA. Java References#Pistoia 04]\] Section 7.4, The Security Manager \[[Gong 03|AA. Java References#Gong 03]\] Section 6.1, Security Manager \[[SecuritySpec 08|AA. Java References#SecuritySpec 08]\] 6.2 SecurityManager versus AccessController |
...
SEC07-J. Minimize accessibility 00. Security (SEC) SEC31-J. Never grant AllPermission to untrusted code