-
CSR
-
Resolution: Approved
-
P3
-
None
-
behavioral
-
minimal
-
-
System or security property
-
JDK
Summary
Define of a subset of JEP 415: Context-Specific Deserialization Filters for JDK 8u. Allow applications to configure context-specific and dynamically-selected deserialization filters via a JVM-wide filter factory that is invoked to select a filter for each deserialization stream.
Problem
Deserializing untrusted data is an inherently dangerous activity because the content of the incoming data stream determines the objects that are created, the values of their fields, and the references between them. In many typical uses the bytes in the stream are received from an unknown, untrusted, or unauthenticated client. By careful construction of the stream, an adversary can cause code in arbitrary classes to be executed with malicious intent. If object construction has side effects that change state or invoke other actions, those actions can compromise the integrity of application objects, library objects, and even the Java runtime. The key to disabling deserialization attacks is to prevent instances of arbitrary classes from being deserialized, thereby preventing the direct or indirect execution of their methods.
Solution
Context-Specific Deserialization Filtering is used to select the filter for each stream when the stream is created, in the constructor or before first invocation to read objects. The filter factory can be provided by the application and is configured to apply across all threads and frameworks. The factory is designed and implemented for the specific application purpose and should take into account all deserialization execution contexts that are to be protected within the Java runtime. The filter factory is invoked in the constructor of ObjectInputStream to select and return the deserialization filter for the stream.
An application’s developer is in the best position to understand the structure and operation of the application’s components. This enhancement enables the application developer to construct and apply filters to every deserialization operation.
Specification
The scope of JEP 415: Context-Specific Deserialization Filters is reduced to
include only the filter factory API and behavior and configuration via command line or
security properties with JDK scope. There are no new classes, methods or fields, and
no utility functions; the behavior is a strict subset of JEP 415.
For JDK 8u, the ObjectInputFilter interface is in the sun.misc
package, whereas for
versions JDK 9 and later, the interface is in the java.io
package.
The behavior is opt-in based on the presence of the jdk.serialFilterFactory
system property on the command line or
the jdk.serialFilterFactory
security property.
If set, the JVM-wide filter factory selects the filter for each stream
when the stream is constructed and when a stream-specific filter is set.
If the JVM-wide filter factory is not set, the behavior is compatible with earlier versions
except that setting the stream-specific filter to null, by calling
sun.misc.ObjectInputFilter.Config.setSerialFilter
, throws java.lang.IllegalStateException
if the JVM-wide filter is non-null.
The use case for setting the stream-specific filter to null to ignore
the JVM-wide filter is a security bug.
If the Java virtual machine is started with the property jdk.serialFilterFactory
system property on the command line or
the jdk.serialFilterFactory
security property, its value
is the fully qualified name of the class to use as the JVM-wide deserialization filter factory.
The system property overrides the security property if both are defined.
Setting the jdk.serialFilterFactory
with System.setProperty
does not set the filter factory.
The class must be public, must have a public zero-argument constructor, implement the
java.util.function.BinaryOperator<sun.misc.ObjectInputFilter>
interface, provide its implementation
and be accessible via the application class loader.
If the filter factory constructor is not invoked successfully, a java.lang.ExceptionInInitializerError
is thrown and subsequent use of the filter factory for deserialization fails with
java.lang.IllegalStateException
.
The JVM-wide filter factory is a function invoked when each java.io.ObjectInputStream
is constructed
and when the stream-specific filter is set using
sun.misc.ObjectInputFilter.Config.setObjectInputFilter(ObjectInputStream, sun.misc.ObjectInputFilter)
.
The parameters are the current filter and a requested filter and it
returns the filter to be used for the stream. When invoked from the ObjectInputStream
constructors,
the first parameter is null
and the second parameter is the static JVM-wide filter
.
When invoked from ObjectInputFilter.Config.setObjectInputFilter
,
the first parameter is the filter currently set on the stream (which was set in the constructor),
and the second parameter is the filter given to ObjectInputFilter.Config.setObjectInputFilter
.
The current and new filter may each be null
and the factory may return null
except
if the current filter is non-null
, the filter factory must return a non-null
filter,
otherwise an IllegalStateException
is thrown from setObjectInputFilter
.
This precaution is taken to prevent unintentional disabling of filtering after it has been enabled.
The factory may throw runtime exceptions to signal incorrect use or invalid parameters.
Note that the filter factory implementation can also use any contextual information at its disposal, for example, extracted from the application thread context, or its call stack, to compose and combine a new filter. It is not restricted to only use its two parameters.
The $JAVA_HOME/lib/security/java.security configuration file for each platform includes the following:
# Deserialization system-wide filter factory
#
# A filter factory class name is used to configure the system-wide filter factory.
# The filter factory selects the sun.misc.ObjectInputFilter to use for each
# ObjectInputStream when invoked with a current and a requested filter.
# The class must be public, must have a public zero-argument constructor, implement the
# java.util.function.BinaryOperator<sun.misc.ObjectInputFilter> interface,
# provide its implementation and be accessible via the application class loader.
# See the release notes for more details.
#
# If the system property jdk.serialFilterFactory is also specified, it supersedes
# the security property value defined here.
#
#jdk.serialFilterFactory=<classname>
- relates to
-
JDK-8270457 Check Java Tutorial for impact of "Implement Context-Specific Deserialization Filters (8u)"
- Closed