JDK-8264860 : Implement Context-Specific Deserialization Filters
  • Type: CSR
  • Component: core-libs
  • Sub-Component: java.io:serialization
  • Priority: P3
  • Status: Closed
  • Resolution: Approved
  • Fix Versions: 17
  • Submitted: 2021-04-07
  • Updated: 2021-06-16
  • Resolved: 2021-06-09
Related Reports
CSR :  
Relates :  
Description
Summary
-------

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 individual deserialization operation.

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 ObjectInputFilter, ObjectInputFilter.Config, and ObjectInputStream classes have been updated and extended to specify the behavior described above and in JEP 415.

A new system property "jdk.serialFilterFactory" has been added to enable configuring the filter factory on the command line.

The methods included in ObjectInputFilter.Config:
 - Get and set the filter factory
 Static methods added to ObjectInputFilter:
 - Creation of filters based on Predicates on classes found in the stream
 - To merge the results of filters
 - To support rejecting classes that are not explicitly allowed or rejected.

The June 8 specdiff is attached with some editorial updates and changes to 
configuration properties and available for browsing at:

  http://cr.openjdk.java.net/~rriggs/8264859-context-filter-factory/filterfactory-diffs/overview-summary.html

The spec and implementation review is in progress:

   https://github.com/openjdk/jdk/pull/3996
Comments
Moving to Approved.
09-06-2021

Added description of throwing ExceptionInInitializer for incomplete initialization and IllegalStateException for APIs that depend on the initialization. Added the system property name jdk.serialFilterFactory. Checked that @ systemProperty is used on in the javadoc of Config to identify the defining occurrence. Specdiff updated (June 8).
08-06-2021

In ObjectInputFilter.Config: "The class must be public, must have a public zero-argument constructor, implement the BinaryOperator<ObjectInputFilter> interface, provide its implementation and be accessible via the application class loader . " So, what happens if all this isn't true? The CSR does not state what new system property is defined. If the property is jdk.serialFilterFactory, I don't see it being covered by a systemProperty javadoc tag (JDK-8211132). Pending the request until these concerns are addressed.
07-06-2021

[~rriggs] Thanks, As per the sequence it looks good. For the case - Return {@code ALLOWED}, if either {@code status} or {@code otherStatus} is {@code ALLOWED}, where the combination status or otherStatus would be only left and applicable is UNDECIDED.
01-06-2021

The statements are intended to be executed sequentially and the most recent should make that clearer than the original. If the first filter returns rejected, it is not necessary to invoke anotherFilter. - Invoke {@code filter} on the {@code FilterInfo} to get its {@code status}; - Return {@code REJECTED} if the {@code status} is {@code REJECTED}; - Invoke {@code anotherFilter} to get the {@code otherStatus}; - Return {@code REJECTED} if the {@code otherStatus} is {@code REJECTED}; - Return {@code ALLOWED}, if either {@code status} or {@code otherStatus} is {@code ALLOWED}, - Otherwise, return {@code UNDECIDED} This should be in the specdiff attached to the CSR as of 28-May.
31-05-2021

ObjectInputFilter.merge I see the conflict in the spec. Return ALLOWED, if either status or otherStatus is ALLOWED, this conflicts with Return REJECTED if the status is REJECTED; Return REJECTED if the otherStatus is REJECTED; case where filter returns ALLOWED and anotherFilter returns REJECTED, What is expected here? this case satisfy both the conditions above. possible spec update: Invoke filter on the FilterInfo to get its status; Return REJECTED if either filter or anotherFilter status is REJECTED; Return ALLOWED, if filter status is ALLOWED and anotherFilter status is not REJECTED; Return ALLOWED, if filter status is not REJECTED and anotherFilter status is ALLOWED; Otherwise, return UNDECIDED
31-05-2021