Penligent Başlık

CVE-2026-68497: Jackson XML Datatype CPU DoS and Fixes

CVE-2026-68497 Jackson XML datatype CPU DoS and fixes editorial cover
Editorial concept illustration, not an observed attack or performance measurement.

CVE-2026-68497 is a Jackson CPU denial-of-service issue at a boundary that is easy to overlook: a JSON string can become an expensive numeric value when it is bound to an XML date or duration type. The CVE record identifies javax.xml.datatype.Duration and javax.xml.datatype.XMLGregorianCalendar deserialization in jackson-databind. The relevant built-in deserializers do not require polymorphic typing, but an application must still route untrusted input to the affected typed binding.

The repair is to use a fixed jackson-databind build and verify that the intended length guard is applied before datatype conversion. Checking only the HTTP body limit, the presence of Jackson, or the absence of polymorphic configuration misses part of that decision. A useful assessment connects the dependency version to the target field type, effective mapper constraints, and the executable that actually handles the input.

Which versions address CVE-2026-68497

Bu published package ranges distinguish two Maven coordinates and five maintained-line fixes. Treat the following as the listed fix thresholds for this CVE, rather than a recommendation to select the oldest release that clears one scanner result.

Maven coordinate and release linePublished affected rangeListed fix threshold
com.fasterxml.jackson.core:jackson-databind, older 2.x lines2.0.0 before 2.18.102.18.10
com.fasterxml.jackson.core:jackson-databind, intermediate 2.x lines2.19.0 before 2.21.62.21.6
com.fasterxml.jackson.core:jackson-databind, 2.222.22.0 before 2.22.22.22.2
tools.jackson.core:jackson-databind, early 3.x lines3.0.0 before 3.1.63.1.6
tools.jackson.core:jackson-databind, 3.23.2.0 before 3.2.23.2.2

A complete upgrade decision also considers the framework’s supported dependency set and other applicable advisories. For example, the separate type-ID cache advisory for CVE-2026-91776 lists later fixes on these lines. Resolving this XML datatype issue alone does not establish that every Jackson finding is resolved. Keep each advisory mapped to the selected release and regression evidence.

When a software vendor supplies Jackson inside its application, use that vendor’s supported update or documented backport. Replacing an embedded JAR manually can make the resulting application difficult to support or reproduce. The release record should identify the package coordinate, resolved version, application artifact, and deployment destination rather than only a source-code dependency edit.

Why a JSON string can bypass a numeric-token assumption

Bu upstream fix discussion concerns applying StreamReadConstraints to XML datatype conversion. A numeric-length policy is only useful at the point where it is consulted. Digits carried inside a JSON string do not automatically receive every check that would apply to a JSON number token before the application chooses a target type.

That makes the destination type important. A string field can remain a string. An XML duration field can cause the same input category to reach a datatype factory that parses numeric components. A QName is another XML-related type with different semantics. Grouping these cases under “XML parsing” hides the actual conversion boundary and makes a regression less precise.

Field or input categoryQuestion to investigateMisleading shortcut
javax.xml.datatype.DurationDoes the selected deserializer validate length before conversion?Assuming a JSON number-token guard covers every string
javax.xml.datatype.XMLGregorianCalendarWhich string and date conversion paths are reachable?Testing only one ordinary timestamp format
java.time.DurationWhich separate module or custom converter handles this type?Treating the shared class name Duration as an exact match
An ordinary String fieldIs conversion performed later in application code?Assuming binding to String eliminates every downstream risk
javax.xml.namespace.QNameIs its intended behavior preserved by the change?Applying an unrelated numeric rule to every XML-related type

The fully qualified type names matter here. The upstream discussion explicitly corrected an ambiguous calendar class name. A code search for Duration should be followed by inspection of imports, annotations, mapper modules, and custom converters. A matching short name is a lead, not a completed exposure assessment.

Trace the real input path rather than relying on a synthetic controller that uses a different mapper. The relevant conversion can be in an API, a message consumer, an imported document workflow, or another application boundary. Identify who can supply the value and where validation happens. A public URL is not required for untrusted input, and a public URL alone does not establish the affected binding.

What the fixed source checks

In the inspected 2.18.10 CoreXMLDeserializers source, the Duration path calls a timestamp-length validator before newDuration. The calendar string path performs the same pre-check before date parsing and its XML lexical fallback. QName follows a separate path. This is a check-before-conversion change, not the removal of XML datatype support.

The corresponding StdDeserializer helper obtains the active stream constraints and applies the maximum-number-length policy. The datatype code checks the whole incoming value as a conservative bound on its numeric components. Do not describe that as counting only the digits in one selected date component.

This distinction affects policy tests. A deliberately small limit can reject a legitimate-looking lexical value because the full value exceeds the configured bound. That can be useful in an isolated regression, but the test’s small number is not a production recommendation. Choose production limits from the accepted data contract and verify representative values after the security update.

Jackson XML datatype conversion with and without an early length guard
Conceptual view based on the fixed source. Accepted values still require normal datatype validation.

Try Penligent for Authorized Security Testing →

A small real-Jackson regression

We ran the following source-file test on OpenJDK 17.0.20, holding jackson-core and jackson-annotations at 2.18.0 and changing jackson-databind between 2.18.9 and 2.18.10. This controlled fixture isolates the databind change; it is not a recommended production dependency combination. The program makes no network requests and uses only short strings. It does not attempt to exhaust a CPU or establish an exploitation rate.

The mapper sets maxNumberLength to 32 and maxStringLength to 256. Two datatype values exceed the first limit while remaining far below the second. Four controls check that ordinary short values, an ordinary String, and a QName still work. The exception inspection distinguishes the intended constraint from an unrelated syntax or mapping failure.

import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.core.StreamReadConstraints;
import com.fasterxml.jackson.core.exc.StreamConstraintsException;
import com.fasterxml.jackson.databind.ObjectMapper;
import javax.xml.datatype.Duration;
import javax.xml.datatype.XMLGregorianCalendar;
import javax.xml.namespace.QName;

public class XmlLengthCheck {
    public static class D { public Duration value; }
    public static class C { public XMLGregorianCalendar value; }
    public static class Q { public QName value; }
    public static class S { public String value; }

    static String json(String value) { return "{\"value\":\"" + value + "\"}"; }
    static void check(ObjectMapper mapper, String value, Class<?> type,
                      boolean expectConstraint) throws Exception {
        boolean constrained = false;
        try {
            mapper.readValue(json(value), type);
        } catch (Exception error) {
            Throwable cause = error;
            while (cause != null) {
                if (cause instanceof StreamConstraintsException) {
                    constrained = true;
                    break;
                }
                cause = cause.getCause();
            }
            if (!constrained) throw error;
        }
        if (constrained != expectConstraint) {
            throw new AssertionError(type.getSimpleName() + ": unexpected guard result");
        }
    }
    public static void main(String[] args) throws Exception {
        boolean fixed = Boolean.parseBoolean(args[0]);
        JsonFactory factory = JsonFactory.builder().streamReadConstraints(
            StreamReadConstraints.builder()
                .maxNumberLength(32).maxStringLength(256).build()).build();
        ObjectMapper mapper = new ObjectMapper(factory);
        check(mapper, "P1D", D.class, false);
        check(mapper, "00:00:00.1", C.class, false);
        check(mapper, "n".repeat(40), Q.class, false);
        check(mapper, "1".repeat(40), S.class, false);
        check(mapper, "P" + "1".repeat(40) + "Y", D.class, fixed);
        check(mapper, "00:00:00." + "1".repeat(40), C.class, fixed);
        System.out.println("databind=" + mapper.version()
            + " expected_fixed=" + fixed + " six checks passed");
    }
}

Save the file as XmlLengthCheck.java. On a JDK with source-file execution, run it with a classpath containing the fixture’s core and annotations JARs and exactly one of the databind versions. CP_OLD and CP_FIXED below are local classpaths you prepare from trusted release artifacts; do not put both databind JARs on one classpath. The test itself stays offline after those artifacts are available.

java --class-path "$CP_OLD" XmlLengthCheck.java false
java --class-path "$CP_FIXED" XmlLengthCheck.java true
Test caseInput size or policyObserved with databind 2.18.9Observed with databind 2.18.10
Short XML durationP1DAcceptedAccepted
Short time-only XML calendar00:00:00.1AcceptedAccepted
QName control40 lettersAcceptedAccepted
Ordinary String control40 digitsAcceptedAccepted
XML duration with a longer year component42 characters totalAcceptedLength constraint
Time-only XML calendar with a longer fraction49 characters totalAcceptedLength constraint

Both runs completed their six expected checks. This establishes the configured guard behavior for these inputs, builds, and runtime. It is not a benchmark of large-input CPU consumption, a claim that the application under review is exposed, or a test of every release branch. A source-level implementation change and a small functional regression support a narrower conclusion than a production exploit reproduction.

The permissive String and QName controls are useful for a second reason: an application that simply rejects every input should not be counted as a successful repair. The regression needs evidence of the intended new rejection alongside continued support for the data it should accept. Keep that balance when adapting the fixture to a real service.

Adapt the test to the application without turning it into a load attack

First establish the actual mapper and target field used by the application. A passing test against a newly constructed ObjectMapper does not establish that a framework-managed mapper has the same effective settings. Custom deserializers or later application conversions can also create a different path. Record the configuration that the test exercises and the code that connects it to the input boundary.

Keep the initial regression small. Choose a test-only length policy that makes the decision observable with short inputs, then check permitted values, rejected values, and the exception category. That avoids needing large allocations or sustained traffic to observe whether the early guard runs. Do not deploy the fixture’s artificial limit to production without a separate compatibility review.

After validating the mechanism, repeat an application-level check with the intended production policy and representative business inputs. Exercise its expected failure response as well as successful conversions. A rejection that becomes an endless retry loop, excessive logging, or an unexpected server error can create a separate operational issue even when the library performs the guard correctly.

Recommended Jackson XML datatype fix and application verification workflow
Recommended workflow. The small Java regression verifies guard behavior, not service-wide CPU resilience.

Try Penligent for Authorized Security Testing →

For message-based systems, define what happens to a rejected message: whether it is discarded, quarantined, reported, or routed to an error handler. The appropriate decision depends on the application contract. Make it visible in the test record rather than inferring success from the absence of a crash. The same principle applies to APIs, where the caller needs a bounded and intentional failure response.

Do not infer service-wide resilience from a single conversion test. Worker limits, upstream request limits, retries, and other application work still matter. The value of this regression is that it isolates one guard and supplies a concrete acceptance condition; it does not replace the broader availability review of an important service.

Inventory dependencies and effective input policy

In an owned Maven project, dependency-tree queries can locate both coordinates. These commands may contact the project’s configured repositories. They are inventory aids and do not establish that any endpoint reaches the affected deserializer.

mvn dependency:tree -Dincludes=com.fasterxml.jackson.core:jackson-databind
mvn dependency:tree -Dincludes=tools.jackson.core:jackson-databind

Inspect the resolved dependency set, the packaged application, and the running deployment. A library can be bundled or relocated inside a vendor artifact, and a container rebuild can preserve an older executable or application archive. Use the organization’s release-evidence process to identify what actually runs rather than treating a changed build file as deployment proof.

Next, compare the intended request and string policies with the accepted data contract. A transport limit bounds one part of input handling; a datatype-level guard bounds a different conversion decision. Keep the two in the assessment rather than assuming one automatically substitutes for the other. Note where a message enters outside the HTTP layer so that an API gateway rule is not mistaken for universal coverage.

For applications that bind to String first, identify the later conversion. A length check performed after the expensive factory call is too late for that call. A reviewed check should precede the conversion and have tests proving that order. This is an application-design observation, not a claim that every custom converter has the same flaw as the built-in path.

Make the regression result portable to a release review

Keep the test fixture separate from the production dependency plan. The controlled comparison above changes one library while holding two others constant so the result is attributable. A production upgrade should instead use the application’s supported dependency alignment. Record both decisions explicitly so a reviewer does not copy the fixture’s older common dependencies into a release merely because the small test passed.

Retain the exact runtime, artifact identities, configuration, test inputs, expected result, and actual exception category. A screenshot saying passed is less useful than a short record another developer can rerun. If a distributor backport uses a different version label, retain its security statement and run the same relevant behavioral check against that delivered artifact. Do not replace documented provenance with a guess based on version ordering.

The sample JSON helper is deliberately limited to its fixed ASCII test values. It is not a general-purpose serializer for arbitrary user input. Applications should continue using their established safe serialization and binding workflow. The fixture’s purpose is to exercise a narrowly defined conversion decision, not to introduce a new input-handling utility into the service.

Interpret unexpected results before changing the expectation. If both library versions reject an input, an earlier string or transport limit may be intervening, or the fixture may not be reaching the intended path. If both accept it, confirm the selected JAR, target type, and effective constraint. If the result is an unrelated parsing exception, fix the fixture rather than counting that exception as evidence of the length guard.

For a release ticket, summarize what the evidence establishes in one concrete sentence: the identified artifact, using the specified mapper policy, rejected the over-policy datatype values through the intended constraint while accepting the selected controls. Keep broader conclusions about real input reachability, service capacity, or historical abuse in their own sections. That makes the regression useful without asking it to prove more than it measured.

Temporary controls and rollout evidence

Bu CVE record’s mitigation guidance recommends avoiding direct untrusted binding to the affected XML types where possible, or applying request and string limits before conversion. Binding to String, checking its length, and converting afterward can make the boundary explicit. Treat such changes as reviewed application behavior and retain a supported library-upgrade plan.

Closure questionEvidence to collectInsufficient substitute
Which input path uses the affected types?Target types, mapper configuration, and trust-boundary reviewThe word Jackson in an inventory
Does the selected build contain the fix?Package coordinate, release provenance, and relevant vendor guidanceA generic scanner label without version evidence
Does the guard run before conversion?A small matched regression and the intended exception categoryAny failed request, regardless of cause
Are valid business values still accepted?Representative data-contract testsRejection of all input
Has the repaired artifact reached the service?Deployment identity tied to the tested artifactA successful build with no rollout evidence
Are other Jackson advisories addressed?Separate release mapping and regression scopeClosing every Jackson finding under one CVE ticket

Choose acceptance criteria before the release window. Record the affected application group, expected fixed artifact, effective policies, positive and negative tests, and the operational owner. If a check fails, preserve the result and stop extending the rollout until its cause is understood. A time-limited maintenance window should not force the team to redefine success after seeing an unexpected result.

Keep security status attached to rollback decisions. Returning to an earlier application release may restore a business workflow while also restoring the prior deserialization behavior. The release record should reopen or retain the corresponding risk decision. An availability recovery and a completed vulnerability repair are separate outcomes.

For authorized security assessments, require findings to state which of these questions were actually answered. When evaluating Penligent or another automated workflow, ask for the tested artifact, input path, and retest evidence. External HTTP behavior can be useful, but it does not automatically reveal a mapper’s effective configuration or prove that a library guard ran internally.

Questions application owners ask

Is CVE-2026-68497 an XML external entity vulnerability

The issue described here is CPU consumption during conversion of JSON strings to specific XML datatypes. Do not infer external entity resolution, file access, or a network callback from the presence of XML in the type names.

Does disabling polymorphic typing remove this path

The relevant built-in bindings do not depend on polymorphic fallback configuration. Check the actual field types and conversion path rather than borrowing the prerequisites from the separate type-ID cache vulnerability.

Does maxNumberLength constrain every digit inside every string

No. A constraint must be invoked by the relevant parsing or conversion path. This fix adds an early check to the specified XML datatype string conversions; ordinary String handling and other converters need their own analysis.

Should production use the test limit of 32

No. That deliberately small value makes the guard observable with tiny inputs. Set production policies from the application’s valid data requirements and verify them with representative tests.

Do the six checks establish a CPU denial of service

They establish acceptance and constraint behavior for a bounded fixture. We did not run large inputs, measure CPU exhaustion, or test an operational endpoint. Keep that result separate from the vendor’s impact assessment.

Is upgrading to the threshold in the table sufficient for all Jackson issues

The table addresses this CVE. Evaluate other applicable advisories and use a supported release compatible with the application. A later cache vulnerability, for example, has its own fix thresholds and regression questions.

The central repair is to enforce the intended boundary before expensive conversion, then prove that the deployed application uses that repaired path. Preserve the distinction between a JSON token, a destination datatype, and a configured constraint. It turns a broad CPU-risk label into a small, repeatable test and an upgrade decision the application owner can verify.

Gönderiyi paylaş:
İlgili Yazılar
tr_TRTurkish