PVADMIN-50363: Fix CVE-2026-6009 in net.sf.jasperreports:jasperreports#3
Open
RxL-Deepak-Agrawal wants to merge 3 commits into
Open
PVADMIN-50363: Fix CVE-2026-6009 in net.sf.jasperreports:jasperreports#3RxL-Deepak-Agrawal wants to merge 3 commits into
RxL-Deepak-Agrawal wants to merge 3 commits into
Conversation
Manually port the upstream value-deserialization filter from Jaspersoft/jasperreports 7.0.7 (commit 10f3862, JSSEC-163) onto the 6.4.0 line. Cherry-pick was infeasible due to layout drift (core/src/main/java vs jasperreports/src) and because the fork inlines filtering in ContextClassLoaderObjectInputStream rather than extending FilteredObjectInputStream. JRValueStringUtils.DefaultSerializer deserialized BASE64-encoded value strings of non-built-in types through a plain ObjectInputStream, allowing arbitrary gadget deserialization (RCE) via a crafted .jasper value or subreport value. It now routes through a new FilteredObjectInputStream guarded by a ValueClassFilter. Changes: - NEW DeserializationFilter: ClassLoaderFilter + isFilteringEnabled() (identical to upstream). - AbstractClassFilter now implements DeserializationFilter. - NEW FilteredObjectInputStream: pluggable DeserializationFilter; resolveClass filtering identical to upstream; reuses the fork's existing CountInputStream so the deserialization.byte.count.limit defense applies to the value path too. - NEW ValueClassFilter (extends AbstractClassFilter): separate value.deserialization.class.whitelist.* namespace; @Property annotations dropped (annotation infra does not exist on the 6.4.0 line). - JRValueStringUtils routes value deserialization through FilteredObjectInputStream + ValueClassFilter, gated by the existing deserialization.class.filter.enabled flag. - New message key value.deserialization.class.not.visible. Value deserialization is now restricted to the curated deserialization whitelist (shared via DeserializationClassWhitelist extensions, upstream-faithful) plus any value.deserialization.class.whitelist.* entries; arbitrary classes are rejected. Reproducer JRValueStringUtilsFilterTest proves the RCE path is closed: an arbitrary Serializable gadget runs only when the filter is disabled, is rejected with the value.deserialization.class.not.visible key when enabled, and the public JRValueStringUtils round-trip blocks it under default (filter-enabled) settings. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Back-ports the upstream fix for CVE-2026-6009 (CWE-502, deserialization → RCE, CVSS 8.7) onto the 6.4.0 fork line.
JRValueStringUtilsdeserialized BASE64-encoded report valuestrings of non-built-in types through a plain, unfiltered
ObjectInputStream, allowing arbitrary gadget-chain deserialization via a crafted.jaspervalue or subreport value. Valuedeserialization is now routed through a filtered stream guarded by a
ValueClassFilter.Manual port — cherry-pick was infeasible (layout drift
core/src/main/javavsjasperreports/src, and the fork inlines filtering inContextClassLoaderObjectInputStreaminstead ofextending
FilteredObjectInputStream).CVE details
net.sf.jasperreports:jasperreports< 7.0.7(fork base 6.4.0.x-Rx in range)10f3862("filter classes on value deserialization", JSSEC-163)Changes
AbstractClassFilternowimplements DeserializationFilter(1-line change).FilteredObjectInputStream— pluggableDeserializationFilter;resolveClassfiltering identical to upstream; reuses the fork's existingCountInputStreamso thedeserialization.byte.count.limitdefense applies to the value path too.ValueClassFilter(extendsAbstractClassFilter) — separatevalue.deserialization.class.whitelist.*namespace;@Propertyannotations dropped (annotation infra absent on6.4.0).
JRValueStringUtilsroutes value deserialization throughFilteredObjectInputStream+ValueClassFilter, gated by the existingdeserialization.class.filter.enabledflag (defaulttrue).value.deserialization.class.not.visible.6.4.0.3-Rx→6.4.0.4-Rx(separate commit).Conflict resolution / adaptation notes
ContextClassLoaderObjectInputStreamleft untouched (it has fork-specific context-classloader fallback + AWTfont logic), so it is not re-parented to
FilteredObjectInputStream.@Propertyannotations dropped — no annotation infrastructure on the 6.4.0 line (same as the CVE-2025-10492 back-port).config.reference.xmlnot ported — that file is a 7.x doc artifact absent on the fork; the runtime property works regardless.ValueClassFilter(viaAbstractClassFilter) loads the sharedDeserializationClassWhitelistextensions, so value deserialization isrestricted to the curated report whitelist plus any
value.deserialization.class.whitelist.*entries. VerifiedAbstractClassFilteris byte-identical to upstream in this respect.Behavior change
With the filter enabled (default), custom Serializable value objects going through the BASE64
DefaultSerializerpath are rejected unless on the curated whitelist or explicitly addedvia
value.deserialization.class.whitelist.<name>. Common typed values (String/Integer/Date/etc.) use their own serializers and are unaffected.Out of scope (follow-up)
The fork's
VirtualizationObjectInputStreamis unfiltered — a pre-existing divergence from the CVE-2025-10492 back-port, not part of this CVE. Recommend a separate ticket.Test plan
mvn compile)JRValueStringUtilsFilterTest(5 cases) passes — gadget executes when disabled, blocked when enabled (value.deserialization.class.not.visible), value-whitelist namespacehonored, shared report whitelist inherited, end-to-end
JRValueStringUtilsround-trip blocks gadget under defaultsContextClassLoaderObjectInputStreamFilterTest(4 cases) still passesTicket: PVADMIN-50363 · Epic: PVADMIN-50285