The filter factory mechanism is opt-in depending on the system property jdk.serialFilterFactory.
A check is added to ensure that a stream-specific filter does not easily disable the configured filter by setting the filter to null; the check is stricter in JEP 415 than in JEP 290. The use of stream-specific filters is thought to be minimal and the use case for setting it to null is considered a security bug.The filter factory mechanism is opt-in depending on the system property jdk.serialFilterFactory. A check is added to ensure that a stream-specific filter does not easily disable the configured filter by setting the filter to null; the check is stricter in JEP 415 than in JEP 290. The use of stream-specific filters is thought to be minimal and the use case for setting it to null is considered a security bug.
System or security property
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.
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.
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.
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
The behavior is opt-in based on the presence of the
system property on the command line or
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
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
system property on the command line or
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.
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
is thrown and subsequent use of the filter factory for deserialization fails with
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
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
the first parameter is
null and the second parameter is the
static JVM-wide filter.
When invoked from
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
The current and new filter may each be
null and the factory may return
if the current filter is
non-null, the filter factory must return a
IllegalStateException is thrown from
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>