According to the Java API [[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. 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 tied to the AccessController
class. The former is used as a hub for access control whereas the latter is the actual implementer of the 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 because 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.
Regarding the implementation and use of custom security managers, the Java Security Architecture Specification [[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 byAccessController
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. Note that the documentation of some APIs, for example the java.io.FileReader
class, may not contain information about the SecurityException
because it is a subclass of RuntimeException
; it is not mandatory to document runtime exceptions. 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 permit the actions.
Noncompliant Code Example
This noncompliant code example does not install the security manager from the command line (assuming that the security manager is not set programatically).
java LocalJavaApp
Compliant Solution
Any Java program (bean, servlet or application) can instantiate a SecurityManager
programatically in the absence of a default, global security manager that does not permit this operation. Applications designed to run locally can use a default global security manager by explicitly setting a flag on the command line while invoking the application. The command line option is usually desired when applications must be prohibited from installing custom security managers programatically and must obey 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 allowable actions.
java -Djava.security.manager -Djava.security.policy=policyURL LocalJavaApp
Even a custom security manager can be made the default and enforced globally from the command line by specifying its absolute path location immediately after an equal-to sign that must appear after the -Djava.security.manager
flag. If it is known in advance that the user prefers using the default global security manager installed from the command line, invoking the setSecurityManager()
method can be forgone in code. In fact, using this method will throw a SecurityException
if the current security policy enforced by the global security manager does not permit replacements (by not granting the RuntimePermission("setSecurityManager")
).
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, the double equals (==
) idiom should be used instead of the single equals =
.
java -Djava.security.manager -Djava.security.policy==policyURL LocalJavaApp
The appletviewer
automatically installs a security manager with the standard policy file. To specify additional policy files, use the -J
flag.
appletviewer -J-Djava.security.manager -Djava.security.policy==policyURL LocalJavaApp
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]] discusses writing policy files in depth.
Noncompliant Code Example
Even when the SecurityManager
API is used, there can be instances where the appropriate checks are not installed. This noncompliant code example passes a null
value to the setSecurityManager
method that is responsible for setting the expected SecurityManager
argument. As a result, no security manager is installed (assuming that the security manager is not installed from the command line).
try { System.setSecurityManager(null); } catch (SecurityException se) { // cannot set security manager, log to file }
Compliant Solution
This compliant solution demonstrates how a custom SecurityManager
class called CustomSecurityManager
can be instantiated by invoking its constructor with a password and set as the default security manager. The APIs that have security checks built into them will use the custom security manager subsequently.
try { System.setSecurityManager(new CustomSecurityManager("password here")); } catch (SecurityException se) { // 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()
).
try { System.setSecurityManager(new SecurityManager()); } catch (SecurityException se) { // cannot set security manager, log to file }
Risk Assessment
Running Java code without a Security Manager being set means that there is no restrictive sandbox and arbitrary code may get executed.
Rule |
Severity |
Likelihood |
Remediation Cost |
Priority |
Level |
---|---|---|---|---|---|
ENV30- 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
[[API 06]] Class SecurityManager, Class AccessControlContext, Class AccessController
[[Policy 02]]
[[Pistoia 04]] Section 7.4, The Security Manager
[[Gong 03]] Section 6.1, Security Manager
[[SecuritySpec 08]] 6.2 SecurityManager versus AccessController
[[MITRE 09]] CWE ID 358 "Improperly Implemented Security Check for Standard"
ENV03-J. Limit remote uses of JVM Monitoring and Managing 01. Runtime Environment (ENV) ENV31-J. Never grant AllPermission to untrusted code