Skip to content

CVE-2026-49844: Verified Reproduction

CVE-2026-49844: Log4j MapMessage emits invalid JSON for non-finite values

CVE-2026-49844 is verified against org.apache.logging.log4j:log4j-api · maven. Affected versions: >=2.13.1,<2.25.5; >=2.26.0,<2.26.1; >=3.0.0-alpha1,<=3.0.0-beta2. Fixed in 2.25.5; 2.26.1. This medium reproduction includes runnable sandbox proof, artifacts, and a plain-text agent view under REPRO-2026-00286.

REPRO-2026-00286 org.apache.logging.log4j:log4j-api · maven Jul 13, 2026 CVE entry .txt
Severity
MEDIUM
CVSS
6.3
Confidence
HIGH
Reproduced in
11m 14s
Tool calls
170
Spend
$1.95
01 · Overview

What Is CVE-2026-49844?

CVE-2026-49844 is a medium-severity improper-encoding flaw (CWE-116, CVSS 6.3) in Apache Log4j API. When a MapMessage containing non-finite floating-point values is serialized to JSON, Log4j emits invalid JSON that downstream parsers reject. Pruva reproduced it (reproduction REPRO-2026-00286).

02 · Severity & CVSS

CVE-2026-49844 Severity & CVSS Score

CVE-2026-49844 is rated medium severity, with a CVSS base score of 6.3 out of 10.

MEDIUM threat level
6.3 / 10 CVSS base
Weakness CWE-116 — Improper Encoding or Escaping of Output

Medium — meaningful risk under specific conditions. Schedule a fix in the normal cycle.

03 · Affected Versions

Affected org.apache.logging.log4j:log4j-api Versions

org.apache.logging.log4j:log4j-api · maven versions >=2.13.1,<2.25.5; >=2.26.0,<2.26.1; >=3.0.0-alpha1,<=3.0.0-beta2 are affected.

How to Reproduce CVE-2026-49844

$ pruva-verify REPRO-2026-00286
or curl -O https://www.pruva.dev/api/v1/reproductions/REPRO-2026-00286/artifacts/bundle/repro/reproduction_steps.sh && chmod +x reproduction_steps.sh && ./reproduction_steps.sh
Run in a VM or disposable container. This exploits a real vulnerability.
06 · Proof of Reproduction

Proof of Reproduction for CVE-2026-49844

Security impact — reproduced
  • reached the target end-to-end
  • on the real production code path
  • high confidence
  • the upstream fix blocks the same trigger
Trigger

non-finite floating-point values (NaN, Infinity, -Infinity) placed in a logged MapMessage, serialized via getFormattedMessage(["JSON"]) or asJson()

Attack chain
  1. MapMessage.getFormattedMessage(["JSON"])
  2. MapMessage.format(JSON)
  3. MapMessage.asJson(sb)
  4. MapMessageJsonFormatter.format(sb, data)
  5. formatNumber/formatDoubleArray/formatFloatArray
  6. sb.append(doubleNumber/floatNumber) emits bare NaN/Infinity tokens
Runnable proof: reproduction_steps.sh
Captured evidence: vulnerable outputfixed output
How the agent worked 392 events · 170 tool calls · 11 min
11 minDuration
170Tool calls
103Reasoning steps
392Events
3Dead-ends
Agent activity over 11 min
Support
18
Repro
167
Judge
49
Variant
154
0:0011:14

Root Cause and Exploit Chain for CVE-2026-49844

Versions: log4j-api 2.13.1 through 2.25.4, and 2.26.0. (Also 3.0.0-alpha1+ per the Snyk advisory.)Fixed: 2.25.5 and 2.26.1.

CVE-2026-49844 is an improper encoding/serialization flaw in Apache Log4j API's MapMessage JSON output. When a MapMessage containing non-finite floating-point values (NaN, Infinity, -Infinity) is serialized to JSON via MapMessage.asJson() or MapMessage.getFormattedMessage(new String[]{"JSON"}), the MapMessageJsonFormatter emits the bare tokens NaN, Infinity, and -Infinity instead of an RFC 8259-compliant representation. These bare tokens are not valid JSON values, so any conformant downstream JSON parser or log-ingestion system will reject or fail to process the affected log records. This is a bypass of the earlier CVE-2026-34481 fix (which addressed JsonTemplateLayout but did not cover the MapMessage.asJson() code path in log4j-api).

  • Package/component affected: org.apache.logging.log4j:log4j-api — class org.apache.logging.log4j.message.MapMessageJsonFormatter, reached via MapMessage.asJson(StringBuilder) and MapMessage.getFormattedMessage(String[]) with the "JSON" format.
  • Affected versions: log4j-api 2.13.1 through 2.25.4, and 2.26.0. (Also 3.0.0-alpha1+ per the Snyk advisory.)
  • Fixed versions: 2.25.5 and 2.26.1.
  • Risk level: Medium (CWE-116: Improper Encoding or Escaping of Output).
  • Consequences: Malformed JSON in log output. Downstream JSON parsers and log-ingestion/indexing pipelines that enforce RFC 8259 will reject or fail on affected records. An attacker who can influence a floating-point value logged in a MapMessage (e.g., via JsonTemplateLayout's message resolver or any layout relying on MapMessage.asJson()) can inject non-finite values to corrupt log records or disrupt log processing. This is not a remote code execution issue.

Impact Parity

  • Disclosed/claimed maximum impact: Improper encoding of non-finite floating-point values during MapMessage JSON serialization producing output that is not valid JSON (serialization/encoding flaw, other). Explicitly stated as not an RCE issue.
  • Reproduced impact from this run: All 13 test cases (NaN, +Infinity, -Infinity as scalar Double, double[], scalar Float, float[], plus a combined asJson() direct call) produce bare NaN/Infinity/-Infinity tokens in the vulnerable version. A strict RFC 8259 JSON parser (Gson JsonReader with lenient=false) rejects all 13 outputs. The fixed version quotes all values as JSON strings ("NaN", "Infinity", "-Infinity") and all 13 parse successfully.
  • Parity: full — the reproduced behavior exactly matches the disclosed impact (invalid JSON from non-finite values; fix quotes them).
  • Not demonstrated: N/A — no code execution was claimed or expected.

Root Cause

In the vulnerable MapMessageJsonFormatter.java (log4j-api ≤ 2.25.4 / 2.26.0), the formatNumber() method handles Double and Float values by directly appending the primitive to the StringBuilder:

// VULNERABLE (rel/2.25.4)
} else if (number instanceof Double) {
    final double doubleNumber = (Double) number;
    sb.append(doubleNumber);          // <-- produces "NaN", "Infinity", "-Infinity"
} else if (number instanceof Float) {
    final float floatNumber = (float) number;
    sb.append(floatNumber);           // <-- produces "NaN", "Infinity", "-Infinity"
}

Java's StringBuilder.append(double) delegates to Double.toString(double), which returns the strings "NaN", "Infinity", and "-Infinity" for non-finite values. These are bare literals in the JSON output — they are not enclosed in quotes and are not valid JSON number syntax per RFC 8259 §6 (which only permits finite numbers). The same issue exists in formatDoubleArray() and formatFloatArray(), which also call sb.append(item) directly for array elements.

The call chain is:

MapMessage.getFormattedMessage(new String[]{"JSON"})
  → MapMessage.format(MapFormat.JSON, sb)
    → MapMessage.asJson(sb)                         [protected]
      → MapMessageJsonFormatter.format(sb, data)
        → formatNumber(sb, number) / formatDoubleArray(...) / formatFloatArray(...)

Fix (PR #4163, merged as commit 19edb23/squash c7103d5 on 2.x; feadf8eb on 2.25.x; 1352b987 on 2.26.x): The fix adds two private helper methods that check Double.isFinite() / Float.isFinite() and, for non-finite values, call formatString() to wrap the value in JSON string quotes:

// FIXED (rel/2.25.5)
private static void formatDouble(StringBuilder sb, double doubleNumber) {
    if (!Double.isFinite(doubleNumber)) {
        formatString(sb, Double.toString(doubleNumber));  // quotes: "NaN", "Infinity", etc.
    } else {
        sb.append(doubleNumber);
    }
}

All sb.append(doubleNumber) / sb.append(floatNumber) / sb.append(item) call sites in formatNumber(), formatDoubleArray(), and formatFloatArray() are replaced with calls to formatDouble() / formatFloat().

Reproduction Steps

  1. Script: bundle/repro/reproduction_steps.sh (self-contained, idempotent).
  2. What the script does:
    • Installs OpenJDK 17 if not present.
    • Downloads the official Apache-published log4j-api artifacts from Maven Central: log4j-api-2.25.4.jar (vulnerable, built from tag rel/2.25.4) and log4j-api-2.25.5.jar (fixed, built from tag rel/2.25.5). Also downloads gson-2.11.0.jar for strict JSON validation.
    • Verifies via javap that the vulnerable jar lacks formatDouble()/formatFloat() helper methods and the fixed jar has them.
    • Compiles bundle/repro/NonFiniteJsonTest.java — a Java harness that creates a concrete MapMessage subclass and exercises both getFormattedMessage(new String[]{"JSON"}) (public API) and asJson(StringBuilder) (protected, via subclass) with NaN, +Infinity, -Infinity as scalar double/float and as double[]/float[] array elements (13 total cases).
    • Runs the harness against each jar. The harness detects bare (unquoted) non-finite tokens via a character-level scanner and validates each output with a strict RFC 8259 JSON parser (Gson JsonReader with setLenient(false) + skipValue()).
    • Emits a machine-readable VERDICT|... line and writes bundle/repro/runtime_manifest.json.
  3. Expected evidence of reproduction:
    • Vulnerable 2.25.4: bare=13 quoted=0 parseFail=13 — all outputs contain bare NaN/Infinity/-Infinity and fail strict JSON parsing.
    • Fixed 2.25.5: bare=0 quoted=13 parseFail=0 — all outputs quote the values as JSON strings and parse successfully.

Evidence

  • Log files:
    • bundle/logs/vulnerable_output.log — full harness output for vulnerable log4j-api 2.25.4
    • bundle/logs/fixed_output.log — full harness output for fixed log4j-api 2.25.5
    • bundle/logs/compile.log — javac compilation output
  • Key excerpts (vulnerable 2.25.4):
    JSON output: {"number":NaN}
    >> BARE non-finite token detected (invalid JSON per RFC 8259)
    >> strict JSON parse FAILED (invalid per RFC 8259)
    
    JSON output: {"numbers":[-Infinity]}
    >> BARE non-finite token detected (invalid JSON per RFC 8259)
    >> strict JSON parse FAILED (invalid per RFC 8259)
    
    SUMMARY: bare=13, quoted=0, parseFail=13
    VERDICT|2.25.4-vulnerable|VULNERABLE|bare=13|quoted=0|parseFail=13
    
  • Key excerpts (fixed 2.25.5):
    JSON output: {"number":"NaN"}
    >> non-finite value is QUOTED (valid JSON string)
    >> strict JSON parse OK (valid RFC 8259 JSON)
    
    JSON output: {"numbers":["-Infinity"]}
    >> non-finite value is QUOTED (valid JSON string)
    >> strict JSON parse OK (valid RFC 8259 JSON)
    
    SUMMARY: bare=0, quoted=13, parseFail=0
    VERDICT|2.25.5-fixed|FIXED|bare=0|quoted=13|parseFail=0
    
  • javap verification:
    • Vulnerable 2.25.4 MapMessageJsonFormatter methods: no formatDouble(, no formatFloat(.
    • Fixed 2.25.5 MapMessageJsonFormatter methods: has formatDouble(StringBuilder, double) and formatFloat(StringBuilder, float).
  • Environment: OpenJDK 17.0.19, Gson 2.11.0 (strict JSON validator), official Apache log4j-api jars from Maven Central (verified identical to source-built jar from rel/2.25.4 tag — same file size 351127 bytes).
  • Runtime manifest: bundle/repro/runtime_manifest.json

Recommendations / Next Steps

  • Upgrade guidance: Upgrade log4j-api to version 2.25.5+ (2.25.x line) or 2.26.1+ (2.26.x line). If on 3.0.0-alpha, monitor for a fix.
  • Suggested fix approach: Already implemented in PR #4163 — gate non-finite Double/Float values through formatString() so they are emitted as JSON strings. This mirrors Jackson's JsonWriteFeature#WRITE_NAN_AS_STRINGS behavior.
  • Testing recommendations: The fix includes regression tests (MapMessageTest.testJsonFormatterDoubleNonFiniteSupport and testJsonFormatterFloatNonFiniteSupport) that parameterize over NaN, +Infinity, -Infinity for both double and float. Any future changes to MapMessageJsonFormatter should ensure these tests continue to pass. Consider adding strict-JSON-parser validation to CI for all MapMessage JSON output.
  • Downstream mitigation: Log-ingestion systems that use lenient JSON parsers (e.g., Gson default mode, some JavaScript engines) may silently accept bare NaN/Infinity, but strict parsers (RFC 8259) will reject them. Validate log JSON output with a strict parser.

Additional Notes

  • Idempotency confirmation: The script was run twice consecutively; both runs produced identical results (exit code 0, bare=13 for vulnerable, bare=0 for fixed). The script skips re-downloading jars if they already exist.
  • Source build verification: In addition to the Maven Central artifacts, the log4j-api module was built from source at tag rel/2.25.4 using Maven (mvn -pl log4j-api-java9,log4j-api -am install -DskipTests). The source-built jar (log4j-api-2.25.4.jar, 351127 bytes) is byte-size-identical to the Maven Central artifact, confirming the published jar matches the repository source.
  • Edge cases covered: The harness tests both scalar and array forms for both Double and Float, covering all code paths in formatNumber(), formatDoubleArray(), and formatFloatArray(). The BigDecimal path is unaffected (it already uses toString() which never produces non-finite tokens).
  • Scope: This is a library_api claim (claimed_surface=library_api, required_entrypoint_kind=function_call). The reproduction exercises the real MapMessage.getFormattedMessage(["JSON"]) and MapMessage.asJson() functions from the official Apache log4j-api artifacts. No service/network boundary is involved.

CVE-2026-49844 Reproduction Transcript

The agent's step-by-step process — every tool call, every handoff, the moment the exploit fired.

Full session Replay every step — scrub the timeline or play it back.

Event 1/40
0:000:42
0:00
session startedaccounts/fireworks/routers/glm-5p2-fast · CVE-2026-49844 · REPRO-20
0:04
0:06
web search
0:08
web search
0:14
0:15
web search
0:17
0:19
0:21
0:23
web search
0:30
0:30
extract_facts
no facts extracted
0:31
0:31
0:31
supportrepro
0:33
0:33
0:33
0:34
0:34
0:34
0:34
0:36
0:36
0:36
0:36
0:37
0:37
0:40
0:42
web search
08 · How to Fix

How to Fix CVE-2026-49844

Upgrade org.apache.logging.log4j:log4j-api · maven to 2.25.5; 2.26.1 or later.

Coming soon

Step-by-step mitigation and hardening guidance for CVE-2026-49844 — configuration checks, workarounds where no patch exists, and how to verify you're protected — is on the way.

10 · FAQ

FAQ: CVE-2026-49844

Is CVE-2026-49844 a bypass of an earlier fix?

Yes. It bypasses the incomplete fix for CVE-2026-34481, which corrected JsonTemplateLayout's JsonWriter but did not cover the MapMessage.asJson() / getFormattedMessage(["JSON"]) code path in log4j-api.

Which Log4j versions are affected by CVE-2026-49844, and where is it fixed?

org.apache.logging.log4j:log4j-api is affected in >= 2.13.1 < 2.25.5, >= 2.26.0 < 2.26.1, and >= 3.0.0-alpha1 <= 3.0.0-beta2. It is fixed in 2.25.5 and 2.26.1 — upgrade to the corresponding patched release.

How severe is CVE-2026-49844?

It is rated medium severity (CVSS 6.3). The impact is availability/integrity of log processing — malformed JSON log records that break downstream parsers — rather than code execution.

How can I reproduce CVE-2026-49844?

Download the verified script from this page and run it in an isolated environment against an affected log4j-api version. It logs a MapMessage containing NaN/Infinity, serializes via asJson(), and shows the bare non-finite tokens producing invalid JSON — which the fixed versions no longer emit.
11 · References

References for CVE-2026-49844

Authoritative sources for CVE-2026-49844 — official vulnerability databases and the upstream advisory. Pruva's reproduction verifies the issue firsthand; these are the primary records to corroborate it.