Versions Compared

Key

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

Wiki MarkupAccording to the Java API Class {{SecurityManager}} documentation \ [[API 06|AA. Java References#API 06]\]:API 2014],

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

A security manager may be associated with any Java code.

The applet As an example, the security manager denies applets all but the most essential privileges. It is designed to protect against inadvertent system modification, information leakage, and user impersonation. The use of security managers is not limited to client-side protection. Web servers, such as Tomcat and WebSphere, use this facility to isolate trojan servlets and malicious Java Server Pages (JSP) code as well as to protect sensitive system resources from inadvertent access.

Java applications that run from the command line can set a default or custom security manager using a command-line flag. Alternatively, it is possible to install a security manager programmatically. Installing a security manager programmatically helps create a default sandbox that allows or denies sensitive actions on the basis of the security policy in effect.

From Java 2 SE Platform onwardsonward, SecurityManager is a non-abstract nonabstract class. As a result, there is no explicit requirement of overriding to override its methods. To create and use a security manager programmatically, the code must have the runtime permissions createSecurityManager (to instantiate SecurityManager and avoid certain information leakage) and setSecurityManager (to install it). These permissions are checked only if a security manager is already installed. This is useful for situations in which a default security manager is in place, such as on a virtual host, and individual hosts must 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 provides the implementer actual implementation of a particular the access control algorithm. Two requirements necessitate the use of the The security manager :supports

  • Providing backward compatibility: Legacy code often contains custom implementations of the security manager class because it was originally abstract.
  • Defining custom policies: It is sometimes desired to subclass Subclassing the security manager to define permits definition of custom security policies (for example, multilevel, coarse, or fine grained security policies with system wide application.grain).

Regarding the implementation and use of custom security managers as opposed to default ones, the Java security architecture specification [SecuritySpec 2010] states Wiki MarkupThe 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.

Noncompliant Code Example

The worst form of non-compliance is not using the the security manager at all. Even when used, there can be cases where the appropriate checks are not installed. In the noncompliant code that follows, a null value has been passed to the setSecurityManager method that is responsible for establishing a current instance of SecurityManager. Moreover, the checkPermission (or any check*) method has not been used.

Code Block
bgColor#FFcccc

try {
  System.setSecurityManager(null);
} catch (SecurityException se) { System.out.println("SecurityManager is already set!"); }

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. In the noncompliant example highlighted next, this flag has not been used which circumvents all SecurityManager checks.

Code Block
bgColor#FFcccc

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. 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"); }

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

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"); }

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
bgColor#ccccff

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("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
bgColor#ccccff

// 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 follows:

Code Block
bgColor#ccccff

java -Djava.security.manager -Djava.security.policy=policyURL LocalJavaApp

In this case, note that the setSecurityManager() method can be forgone and substituted with just the getSecurityManager() method as the manager has already been installed using the command line flag.

Many of the Java SE APIs perform 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. Because SecurityException is a subclass of RuntimeException, the declarations of some API methods (for example, those of the java.io.FileReader class) may lack a throws clause that lists the SecurityException. Avoid depending on the presence or absence of security manager checks that are not specified in the API method's documentation.

Noncompliant Code Example (Command-Line Installation)

This noncompliant code example fails to install any security manager from the command line. Consequently, the program runs with all permissions enabled; that is, there is no security manager to prevent any nefarious actions the program might perform.

Code Block
bgColor#FFcccc
java LocalJavaApp

Compliant Solution (Default Policy File)

Any Java program can attempt to install a SecurityManager programmatically, although the currently active security manager may forbid this operation. Applications designed to run locally can specify a default security manager by use of a flag on the command line at invocation.

The command-line option is preferred when applications must be prohibited from installing custom security managers programmatically and are required to abide by the default global security policy under all circumstances. This compliant solution installs the default security manager using the appropriate command-line flags. The security policy file grants permissions to the application for its intended actions.

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

The command-line flag can specify a custom security manager whose policies are enforced globally. Use the -Djava.security.manager flag, as follows:

Code Block
java -Djava.security.manager=my.security.CustomManager ...

If the current security policy enforced by the current security manager forbids replacements (by omitting the RuntimePermission("setSecurityManager")), any attempt to invoke setSecurityManager() will throw a SecurityException.

The default security policy file java.policy—found in the /path/toThe 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 UnixUNIX-like systems and its equivalent on Microsoft Windows systems. There is also a user systems—grants a few permissions (reading system properties, binding to unprivileged ports, and so forth). A user-specific policy file may be located in the user's home directory. The union of both these policy files defines specifies the permissions given granted to a program. Refer to the The java.security file to set can specify which policy files should be are used. If either of these the systemwide java.policy or java.security files 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 double equals (==) idiom should be used.executing Java program.

Compliant Solution (Custom Policy File)

Use double equals (==) instead of the single equals (=) when overriding the global Java security policy file with a custom policy file:

Code Block
bgColor#ccccff

java -Djava.security.manager \
     -Djava.security.policy==policyURL \
     LocalJavaApp

Compliant Solution (Additional Policy Files)

The appletviewer automatically installs a security manager with the standard policy file. To specify additional policy files, use the -J flag.

Code Block
bgColor#ccccff

appletviewer -J-Djava.security.manager \
             -J-Djava.security.policy==policyURL LocalJavaApp

Wiki Markup
Notably, the policy file specified in the argument is ignored when the {{policy.allowSystemProperty}} property in the security properties file ({{java.security}}) is set to false. Its default value is true. The document "Default Policy Implementation and Policy File Syntax" \[[Policy 02|AA. Java References#Policy 02]\] discusses writing policy files in depth.  

Risk Assessment

Running Java code without a Security Manager being set means that there is no security at all.

Rule

Severity

Likelihood

Remediation Cost

Priority

Level

SEC30-J

high

probable

low

P18

L1

Automated Detection

TODO

Related Vulnerabilities

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

References

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
\[[MITRE 09|AA. Java References#MITRE 09]\] [CWE ID 358|http://cwe.mitre.org/data/definitions/358.html] "Improperly Implemented Security Check for Standard"

Note that the policy file specified in the argument is ignored when the policy.allowSystemProperty property in the security properties file (java.security) is set to false; the default value of this property is true. Default Policy Implementation and Policy File Syntax [Policy 2010] discusses in depth the issues of and syntax for writing policy files.

Noncompliant Code Example (Programmatic Installation)

A SecurityManager can also be activated using the static System.setSecurityManager() method. Only one SecurityManager may be active at a time. This method replaces the currently active SecurityManager with the SecurityManager provided in its argument or no SecurityManager if its argument is null.

This noncompliant code example deactivates any current SecurityManager but does not install another SecurityManager in its place. Consequently, subsequent code will run with all permissions enabled; there will be no restrictions on any nefarious action the program might perform.

Code Block
bgColor#FFcccc
try {
  System.setSecurityManager(null);
} catch (SecurityException se) {
  // Cannot set security manager, log to file
}

An active SecurityManager that enforces a sensible security policy will prevent the system from deactivating it, causing this code to throw a SecurityException.

Compliant Solution (Default Security Manager)

This compliant solution instantiates and sets the default security manager:

Code Block
bgColor#ccccff
try {
  System.setSecurityManager(new SecurityManager());
} catch (SecurityException se) {
  // Cannot set security manager, log appropriately
}

Compliant Solution (Custom Security Manager)

This compliant solution demonstrates how to instantiate a custom SecurityManager class called CustomSecurityManager by invoking its constructor with a password; this custom security manager is then installed as the active security manager.

Code Block
bgColor#ccccff
char password[] = /* initialize */
try {
  System.setSecurityManager(
    new CustomSecurityManager("password here")
  );
} catch (SecurityException se) {
  // Cannot set security manager, log appropriately
}

After this code executes, APIs that perform security checks use the custom security manager. As noted earlier, custom security managers should be installed only when the default security manager lacks the required functionality.

Applicability

Java security fundamentally depends on the existence of a security manager. In its absence, sensitive actions can execute without restriction.

Programmatic detection of the presence or absence of a SecurityManager at runtime is straightforward. Static analysis can address the presence or absence of code that would attempt to install a SecurityManager if the code were executed. Checking whether the SecurityManager is installed early enough, whether it specifies the desired properties, or whether it is guaranteed to be installed may be possible in some special cases but is generally undecidable.

Bibliography

[API 2014]Class SecurityManager
Class AccessControlContext
Class AccessController
[Gong 2003]§6.1, "Security Manager"
[Pistoia 2004]§7.4, "The Security Manager"
[Policy 2010]Default Policy Implementation and Policy File Syntax
[SecuritySpec 2010]§6.2, "SecurityManager versus AccessController"

 

...

Image Added Image Added Image AddedSEC07-J. Minimize accessibility of classes and their members      01. Platform Security (SEC)      SEC31-J. Never grant AllPermission to untrusted code