Contents

Overview

JEP-290 brought support for deserialization filters to Java programming language. Such filtering allows you to control the classes that need to be deserialized using Java serialization.

Deserialization Setup

Helidon default settings forbid any deserialization except for patterns defined in a pattern property of any META-INF/helidon/serial-config.properties on classpath. The patterns are semicolon delimited strings such as io.myapp.**;java.util.HashMap (any subpackage of io.myapp and class java.util.HashMap). Helidon will always add a deny-all filter pattern to the end of the pattern string (to ensure we exclude any unspecified class - we only operate on whitelists)

These defaults can be modified either through system properties or programmatically.

System Property Configuration

The following system properties can be used to control deserialization in Helidon:

System Properties
propertydefault valuedescription
helidon.serialFilter.pattern!*

Filter pattern to use, deny all is always added

helidon.serialFilter.ignoreFilesfalse

Whether to ignore files META-INF/helidon/serial-config.properties in libraries on the classpath

helidon.serialFilter.failure.actionFAIL

Action to do when the configuration of global filter exists and is not consistent with security expectations (for example, contains a pattern to include all)

Options:

  • FAIL - Throw an exception to terminate startup.

  • WARN - Log a warning.

  • IGNORE - Ignore this and continue silently.

helidon.serialFilter.missing.actionCONFIGURE

Action to do when there is no global configuration.

Options:

  • CONFIGURE - Configure the Helidon defaults.

  • FAIL - Throw an exception to terminate startup.

  • WARN - Log a warning.

  • IGNORE - Ignore this and continue silently.

helidon.serialFilter.traceNONE

Tracing configuration for deserialization. Controls what information (if any) will be logged to a logger io.helidon.common.SerializationConfig.TracingObjectInputFilter in INFO log level.

Options:

  • NONE - Do not trace.

  • BASIC - Trace only classes, and only once per class.

  • FULL - Trace all deserialization filter requests.

Programmatic Configuration

Custom SerializationConfig may be registered, but it must be done before Helidon server is started.

Configure Custom Helidon Serialization Config
SerializationConfig.builder()
  .traceSerialization(SerializationConfig.TraceOption.BASIC) 
  .filterPattern(MyType.class.getName())                     
  .ignoreFiles(true)                                         
  .onWrongConfig(SerializationConfig.Action.IGNORE)          
  .build()
  .configure();                                              
Copied
  • Trace first instance of each class that is deserialized.
  • Configure a single class filter pattern (allows only deserialization of class MyType).
  • Ignore files defined in META-INF/helidon/serial-config.properties.
  • In case there is an existing global serialization configuration on JDK, ignore it and continue (global filter cannot be reconfigured).
  • Configure this serialization config as the default for this JVM.

JEP-290 Pattern Syntax

Serialization patterns are fully qualified class names or package names with wildcards delimited with semicolon`;`

  • Package name ending with .* - All classes in the package.

  • Package name ending with .** - All classes in the package and subpackages.

  • FQDN ending with * - Standard wildcard, matches all classes with the prefix.

  • FQDN matches exact class

  • Patterns starting with ! - NOT, rejects pattern if matched.

  • <MODULE_NAME>/<FQDN> - When pattern contains /, name before it marks the module name.

Example of META-INF/helidon/serial-config.properties Content
pattern=java.util.**;!java.util.ArrayList;my.package.*
Copied
Example of Pattern Supplied as a System Property
java -Dhelidon.serialFilter.pattern="java.util.**;!java.util.ArrayList;my.package.*" -jar my-app.jar
Copied

Troubleshooting

The Helidon serialization config filter doesn’t trace the actual rejected classes by default. The logs will show only InvalidClassException with the message filter status: REJECTED.

java.io.InvalidClassException: filter status: REJECTED

To find out which class has been actually rejected, set the helidon.serialFilter.trace system property to either basic or full.

java -Dhelidon.serialFilter.trace=basic -jar ./target/custom-mp.jar

Each accepted or rejected class is logged only once with the basic trace filter setting.

...
ALLOWED class: class java.util.LinkedList, arrayLength: -1, depth: 2, references: 3, streamBytes: 84
REJECTED class: class java.util.ArrayList, arrayLength: -1, depth: 2, references: 3, streamBytes: 90

You can compose proper serialization filter pattern with the list of REJECTED classes.