-
CSR
-
Resolution: Approved
-
P3
-
None
-
behavioral
-
low
-
-
Java API, System or security property
-
SE
Summary
Extend security properties capabilities so files containing properties definitions can include other files inline. When a file is included, all its security properties are added as if defined at that point.
Problem
Multiple JDKs deployed on a system (i.e. different JDK releases) often require common values for security properties. At the moment, it is not possible to define and manage these values in a centralized way. As a result, values need to be defined in each JDK java.security
file separately, leading to duplication and possible misconfiguration. This problem aggravates when switching between sets of properties that constitute security profiles. The existing java.security.properties
mechanism (system property) has drawbacks when used as a workaround to this problem, as the configuration needs to be passed for each JVM execution.
Solution
Introduce a special security property named include which takes a filesystem path as value. Each definition of this property has the effect of including all properties from the referred file in place. With this solution, each JDK java.security
file can include a centralized repository of security properties. Security properties in the centralized repository may be organized per security profile, library component, JDK release, a combination of the previous or any other criteria.
To provide more flexibility, filesystem paths assigned to the new include security property may contain one or multiple placeholders that get expanded to system property values in run time. If the system property referred by the placeholder is not available (i.e. its value is null
), expansion is to the empty string. This behavior makes it possible to parameterize part of the security configuration and switch between a global security profile (default) and alternative profiles on a per-run basis. Notice that this is possible because system properties can be passed as Java launcher arguments. In addition to limiting the scope of a security profile to a single execution, non-privileged users —who are not allowed to modify the java.security file— may benefit from applying a profile that meets their needs. See more about this configuration in subsections Syntax and Examples of Specification.
Specification
Changes to the Java SE specification are required in the Security::getProperty and Security::setProperty APIs as described in this section. In addition, the include security property is assigned special semantics. By default, OpenJDK's java.security
file does not include any other file.
Syntax
The special include property can be defined one or multiple times in a security properties file with a filesystem path value. The effect of each definition is to include a referred security properties file inline, adding all its properties. Included files, as well as files pointed by java.security.properties
, can include other files recursively. Paths may be absolute or relative, and may contain system properties for expansion in the form of ${system.property}
. If a system property does not have a value, it expands to the empty string. Each relative path is resolved against the base file containing its include definition, if local. An error will be thrown if a file cannot be included, either because it does not exist, cannot be resolved, or is recursively included more than once.
java.security
The following paragraphs are proposed for the java.security
file:
The special "include" property can be defined one or multiple times with
a filesystem path value. The effect of each definition is to include a
referred security properties file inline, adding all its properties.
Security properties defined before an include statement may be overridden
by properties in the included file, if their names match. Conversely,
properties defined after an include statement may override properties in
the included file.
Included files, as well as files pointed to by java.security.properties,
can include other files recursively. Paths may be absolute or relative.
Each relative path is resolved against the base file containing its
"include" definition, if local. Paths may contain system properties for
expansion in the form of ${system.property}. If a system property does
not have a value, it expands to the empty string.
An error will be thrown if a file cannot be included. This may happen
if the file cannot be resolved, does not exist, is a directory, there are
insufficient permissions to read it, it is recursively included more than
once, or for any other reason. For a secure JDK configuration, it is
important to review OS write permissions assigned to any file included.
Examples:
1) include ${java.home}/conf/security/extra.security
2) include extra.security
3) include ${java.home}/conf/security/profile${SecurityProfile}.security
Security::getProperty and Security::setProperty APIs
include
is a reserved word not available to define a security property. Any call to java.security.Security.getProperty("include")
or java.security.Security.setProperty("include", ...)
throws an unchecked IllegalArgumentException
exception. The following is proposed to document this change:
/**
* Gets a security property value.
*
* <p>First, if there is a security manager, its
* {@code checkPermission} method is called with a
* {@code java.security.SecurityPermission("getProperty."+key)}
* permission to see if it's ok to retrieve the specified
* security property value.
*
* @param key the key of the property being retrieved.
*
* @return the value of the security property, or {@code null} if there
* is no property with that key.
*
* @throws SecurityException
* if a security manager exists and its {@link
* java.lang.SecurityManager#checkPermission} method
* denies
* access to retrieve the specified security property value
* @throws NullPointerException if key is {@code null}
* @throws IllegalArgumentException if key is reserved and cannot be
* used as a Security property name. Reserved keys are:
* "include".
*
* @see #setProperty
* @see java.security.SecurityPermission
*/
public static String getProperty(String key) {
...
}
/**
* Sets a security property value.
*
* <p>First, if there is a security manager, its
* {@code checkPermission} method is called with a
* {@code java.security.SecurityPermission("setProperty."+key)}
* permission to see if it's ok to set the specified
* security property value.
*
* @param key the name of the property to be set.
*
* @param datum the value of the property to be set.
*
* @throws SecurityException
* if a security manager exists and its {@link
* java.lang.SecurityManager#checkPermission} method
* denies access to set the specified security property value
* @throws NullPointerException if key or datum is {@code null}
* @throws IllegalArgumentException if key is reserved and cannot be
* used as a Security property name. Reserved keys are:
* "include".
*
* @see #getProperty
* @see java.security.SecurityPermission
*/
public static void setProperty(String key, String datum) {
...
}
Examples (valid)
Relative path (multi-platform):
include extra.security
Absolute path using an expanded system property (multi-platform):
include ${java.home}/conf/security/extra.security
Absolute path (Linux):
include /etc/crypto-policies/back-ends/java.config
Absolute path, back-slashes (Windows):
include C:\\Program Files\\Common Files\\OpenJDK\\java.config
Absolute path, forward-slashes (Windows):
include C:/Program Files/Common Files/OpenJDK/java.config
UNC path (Windows):
include \\\\WindowsHost\\Share\\java.config
Switch between profiles via a system property (Linux):
include ${java.home}/conf/security/profile${SecurityProfile}.security
In this case, the file profile.security must exist and may define a default security profile or be empty. Other files such as FIPS.security may define alternative profiles. To apply an alternative profile, the JVM may be launched with the -DSecurityProfile=FIPS
argument. System administrators and packagers have flexibility to establish profile strategies, as the proposed specification does not prescribe system properties names or values.
Examples (invalid)
URLs are not allowed:
include file:///etc/crypto-policies/back-ends/java.config
Included files must exist:
include non-existent-file.security
Directories cannot be included:
include /etc/crypto-policies/back-ends/
- csr of
-
JDK-8319332 Security properties files inclusion
- Resolved