DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Please enter at least three characters to search
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

The software you build is only as secure as the code that powers it. Learn how malicious code creeps into your software supply chain.

Apache Cassandra combines the benefits of major NoSQL databases to support data management needs not covered by traditional RDBMS vendors.

Generative AI has transformed nearly every industry. How can you leverage GenAI to improve your productivity and efficiency?

Modernize your data layer. Learn how to design cloud-native database architectures to meet the evolving demands of AI and GenAI workloads.

Related

  • Improving Java Code Security
  • How Dangerous Is Log4Shell and How it Affects the Java Industry?
  • How To Detect and Secure Your Java App From Log4j Vulnerabilities
  • Agentic AI for Automated Application Security and Vulnerability Management

Trending

  • System Coexistence: Bridging Legacy and Modern Architecture
  • Driving DevOps With Smart, Scalable Testing
  • Proactive Security in Distributed Systems: A Developer’s Approach
  • Prioritizing Cloud Security Risks: A Developer's Guide to Tackling Security Debt
  1. DZone
  2. Coding
  3. Java
  4. Java Serialization Filtering — Prevent 0-Day Security Vulnerabilities

Java Serialization Filtering — Prevent 0-Day Security Vulnerabilities

A simple configuration that requires no code change can save you from a hack such as Log4Shell, even from vulnerabilities we don't know about yet!

By 
Shai Almog user avatar
Shai Almog
DZone Core CORE ·
Feb. 21, 23 · Tutorial
Likes (2)
Comment
Save
Tweet
Share
2.9K Views

Join the DZone community and get the full member experience.

Join For Free

I’ve been a Java developer long enough to remember the excitement when Sun introduced the concept of serialization in the JVM. In the world of C, we could just write a struct into a file, but this was always problematic. It wasn’t portable and had many issues. But for Java, we could just write the class, and it “worked." This was pure magic!

Java was still mostly in use on the client side, and when we thought about security, we had different vulnerabilities in mind. The sandbox occupied most of our security discussions. Fast forward a couple of decades, and today when most developers discuss serialization, the discussion isn’t so positive. Serialization, as Brian Vermeer puts it, is: “the gift that keeps giving.”

In fact, just after I created this video, a new deserialization vulnerability in SnakeYaml was exposed. Serialization is one of the biggest security problems in many programming languages; it isn’t just a JVM problem. Hackers can use tools designed to deliver a serialization exploit chain. You can then generate a gadget used to deliver the exploit without too much knowledge of the system. That is scary stuff.

I’m not a security expert. I care more about the solution. How do we make sure that the next zero-day doesn’t affect us?

How do we harden our server code against serialization attacks? 

Do We Need Serialization?

We rarely need serialization. Ideally, if you can remove serialization entirely from your code and can avoid 3rd party code that uses serialization, you can block it completely. This will mean that even if a zero-day comes up, the serialization portion will fail. You might have a bug, but it won’t be an exploitable vulnerability.

Sometimes we need a bit of serialization. In that case, we can include only the well-known classes needed and block everything else out.

JEP 290: Serialization Filtering

The solution came in Java 9 in the form of serialization filtering as part of JEP 290. There are critical patch updates for older JDKs, such as JDK 8u121. So if you must stay in an older version, it’s still possible to use this feature.

It is possible to use this feature with no code changes, although we might want to change the code for additional functionality. The fundamental problem is testing that important systems don’t break. We might run into difficulty when verifying serialization usage, e.g., in distributed caching layers. A cache might serialize objects to synchronize them between nodes over the network. We might miss that dependency when running tests locally but fail in production. In those cases, you can follow the strategies listed below to solve the problems.

Whitelist vs. Blacklist

There are two approaches we can take when filtering specific serializable objects:

  • Whitelist — Block everything and allow specific classes or packages in.

  • Blacklist — Block specific problematic classes and packages.

A blacklist lets us block well-known vulnerabilities, and that might be enough. But we have no guarantee that we blocked everything. A whitelist is usually the more secure option, yet it might break your code if you missed a class that’s required in an edge case.

We can set the filter on the JDK itself by editing the java. security properties file. That might make sense if you package a JDK with your application. Personally, I prefer using the command line argument to configure that, e.g.:

 
java “-Djdk.serialFilter=!*” -jar MyJar.jar


This command will block all serialization. Notice I need to use the quotes to prevent bash from expanding the star sign. The exclamation point means we wish to block, and the star means we block everything.

The following code is a blacklist. We’re blocking a specific package. We can also narrow it down to a specific class. But as I said before, this isn’t ideal:

 
java “-Djdk.serialFilter=!mypackage.*” -jar MyJar.jar


Besides the inherent problems with the blacklist, a major problem is knowing what to block. There are obvious targets like classes that have been vulnerable in the past, e.g.:

  • java.rmi.server.UnicastRemoteObject

  • java.util.logging.Handler

  • java.util.zip.Inflater

  • org.apache.commons.collections.functors.InvokerTransformer

  • org.apache.commons.collections4.functors.InvokerTransformer

Unfortunately, this list is not exhaustive, and I couldn’t find any list that I can use as a source for a proper blacklist. We can look through the Common Vulnerabilities and Exposures (CVE) database for exploits, but that’s painstaking work.

Finally, we have a whitelist where we allow the classes under the package mypackage. We can serialize them as usual. The JVM seamlessly blocks everything else. This is pretty close to the ideal situation. We can add additional classes and packages as necessary by adding them and separating them with a semicolon:

 
java “-Djdk.serialFilter=mypackage.*;!*” -jar MyJar.jar


What About Complexity?

How do you know which classes are serialized in the code? How do you get an alert if your code blocked a serialization attempt? This might be something you would want to track since it might be the system breaking, or it might be an attempted hack. Both are valid reasons for an alert. You can’t do that declaratively, but you can write code that can use sophisticated logic to determine whether serialization should succeed.

This is a sample from the Oracle documentation of a simple serialization filter. Notice it can reject the serialization or leave it undecided. This is part of a filter chain where each stage in the validation process can reject the serialization or pass it on to the next stage. We can bind the filter globally as we do here or do it on a per-stream basis. The API is remarkably flexible and provides a lot of information about the process:

 
ObjectInputFilter.Config.setSerialFilter(info -> info.depth() > 10 ? Status.REJECTED : Status.UNDECIDED); 


TL;DR

You should always use serialization filtering when running a JVM deployment. This should always be the case. 

Serialization filtering was backported to older JVM versions, so there is absolutely no excuse.

Serialization filtering requires no code changes, and we can enable it via global configuration or command line.

At the very least, you can use it to blacklist known vulnerabilities. Ideally, we should block all serialization and whitelist specific classes or packages as needed.

Java virtual machine Serialization Vulnerability Blocks Java (programming language) security

Published at DZone with permission of Shai Almog, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

Related

  • Improving Java Code Security
  • How Dangerous Is Log4Shell and How it Affects the Java Industry?
  • How To Detect and Secure Your Java App From Log4j Vulnerabilities
  • Agentic AI for Automated Application Security and Vulnerability Management

Partner Resources

×

Comments
Oops! Something Went Wrong

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends:

Likes
There are no likes...yet! 👀
Be the first to like this post!
It looks like you're not logged in.
Sign in to see who liked this post!