Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8268701

Implement Context-Specific Deserialization Filters (8u)

XMLWordPrintable

    • Icon: CSR CSR
    • Resolution: Approved
    • Icon: P3 P3
    • 8-pool
    • core-libs
    • None
    • behavioral
    • minimal
    • Hide
      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.
      Show
      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
    • 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>

            rriggs Roger Riggs
            rriggs Roger Riggs
            Brent Christian
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated:
              Resolved: