CVE-2026-34481
This Vulnerability has been fixed in the Never-Ending Support (NES) version offered by HeroDevs.
Overview
Apache Log4j 2 ships JsonTemplateLayout (in the separately-published log4j-layout-template-json artifact) as the recommended JSON output layout for log events. Applications wire it into their appenders to emit one JSON document per log event, typically consumed downstream by Logstash, Fluent-bit, Vector, Datadog's pipeline agent, Elasticsearch's _bulk indexing API, or another collector that strict-parses each line.
A high-severity vulnerability (CVE-2026-34481, classified as CWE-116 Improper Encoding or Escaping of Output) has been identified in the layout's internal JsonWriter. The writeNumber(float) and writeNumber(double) methods called stringBuilder.append(number) unconditionally, which the JDK specifies as equivalent to appending Float.toString(value) / Double.toString(value). For non-finite values, those methods emit the literal tokens NaN, Infinity, and -Infinity, none of which are valid JSON per RFC 8259 §6 ("Numeric values that cannot be represented in the grammar below (such as Infinity and NaN) are not permitted"). When a log event carries an attacker-controlled non-finite float or double (typically via a MapMessage whose values originate from untrusted input), the resulting JSON line is unparseable. Strict downstream collectors raise a parsing error and either silently drop the line, route it to a dead-letter index, or back-pressure the pipeline at the agent.
Per OWASP: "Denial of Service (DoS) is an attack against the availability of a system or service." The practical effect of this defect is denial of service for the logging pipeline downstream of the affected application: an attacker who can land a non-finite float into any logged MapMessage can cause the log record that would have flagged their actions to be discarded before it reaches the SIEM or audit store.
NVD assigns CVSS v3.1 base score 7.5 (High) with vector AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:N; Apache assigns CVSS v4.0 base score 6.3 (Medium) with vector CVSS:4.0/AV:N/AC:H/AT:P/PR:N/UI:N/VC:N/VI:N/VA:N/SC:N/SI:L/SA:N. The two vectors disagree because exploitation requires JsonTemplateLayout to be configured (it is opt-in; the default Log4j layout is PatternLayout) and the application must log a MapMessage containing an attacker-influenced floating-point value (plain string fields, integers, and finite doubles are not in scope). The application itself has no in-process compromise, no memory corruption, and no availability degradation; the integrity score reflects the integrity of the log-record stream that downstream tooling consumes.
This issue affects Apache Log4j 2 versions 2.14.0 through 2.25.3 (the lower bound matches when JsonTemplateLayout was first donated to the project), and pre-release versions 3.0.0-alpha1 through 3.0.0-beta3.
Details
Module Info
- Product: Apache Log4j 2
- Affected packages: log4j-layout-template-json
- Affected versions: >=2.14.0 <=2.25.3, >=3.0.0-alpha1 <=3.0.0-beta3
- GitHub repository: https://github.com/apache/logging-log4j2
- Published packages: https://central.sonatype.com/artifact/org.apache.logging.log4j/log4j-layout-template-json
- Package manager: Maven
- Fixed in:
- NES for Apache Log4j 2 2.17.x
- OSS Apache Log4j 2 2.25.4
Vulnerability Info
The vulnerability is in org.apache.logging.log4j.layout.template.json.util.JsonWriter, the internal writer that backs JsonTemplateLayout. Two methods on JsonWriter (writeNumber(float) and writeNumber(double)) were unguarded against non-finite values.
An application is vulnerable when both of the following are true:
- The application uses Apache Log4j 2 between 2.14.0 and 2.25.3 inclusive (or a 3.x pre-release in the affected range)
- The application's deployed Log4j configuration uses JsonTemplateLayout and at runtime logs a MapMessage (or a StructuredDataMessage, which extends MapMessage) whose values originate from untrusted input, with at least one value being a non-finite float or double
When those conditions are met, the path from the MapMessage value to the broken writer runs through JsonWriter#writeValue(Object) → writeNumber(Number) → writeNumber(float) / writeNumber(double), producing a literal NaN, Infinity, or -Infinity token in the JSON output. There is no centralized value sanitization upstream of the writer.
Prior to the fix, the two methods were:
public void writeNumber(final float number) {
stringBuilder.append(number);
}
public void writeNumber(final double number) {
stringBuilder.append(number);
}
StringBuilder#append(float) and StringBuilder#append(double) are specified as appending Float.toString(value) / Double.toString(value), both of which emit NaN, Infinity, or -Infinity for non-finite inputs. Those tokens leave the writer as bare identifiers in the JSON stream (not enclosed in quotes), violating RFC 8259's number grammar.
The fix wraps non-finite values in JSON string literals, mirroring Jackson's JsonWriteFeature.WRITE_NAN_AS_STRINGS behavior (so NaN becomes the string "NaN", which is valid JSON and survives strict downstream parsing):
public void writeNumber(final float number) {
// Follows the same logic as Jackson's JsonWriteFeature#WRITE_NAN_AS_STRINGS feature.
if (!Float.isFinite(number)) {
writeString(Float.toString(number));
} else {
stringBuilder.append(number);
}
}
public void writeNumber(final double number) {
// Follows the same logic as Jackson's JsonWriteFeature#WRITE_NAN_AS_STRINGS feature.
if (!Double.isFinite(number)) {
writeString(Double.toString(number));
} else {
stringBuilder.append(number);
}
}
New parameterized regression tests in JsonWriterTest exercise Float.NaN, Float.POSITIVE_INFINITY, Float.NEGATIVE_INFINITY, and the corresponding double values, asserting that each is emitted as a JSON string whose body is the platform Float.toString / Double.toString of the input, i.e. "NaN", "Infinity", "-Infinity".
JsonTemplateLayout was donated to the Apache Log4j project from a sibling project (log4j2-logstash-layout) in commit c11ed6f9feb68206bbf1cf689f2d85a1640b2fe3 ("#335 Initial import of JsonTemplateLayout from LogstashLayout") on 2020-08-19, and the unguarded stringBuilder.append(number) pattern was present from the very first commit. The artifact module was renamed from log4j-layout-json-template to log4j-layout-template-json in commit 4e70878a6354c3394d47bc0c99f4a41997683082 (2020-08-25) without changing the writer methods. The first public release containing the vulnerable code was Apache Log4j 2.14.0 (2020-11-06), which matches the advisory's lower bound. Releases 2.13.3 and earlier do not include JsonTemplateLayout and are not in scope.
Mitigation
Only recent versions of Apache Log4j 2 receive community support and updates. Older versions have no publicly available fixes for this vulnerability.
Users of the affected components should apply one of the following mitigations:
- Upgrade to a currently supported version of Apache Log4j 2. The OSS fix ships in Apache Log4j 2.25.4 and later.
- Validate or coerce numeric values at the application boundary before placing them in a MapMessage: reject non-finite float and double values with Float.isFinite(...) / Double.isFinite(...) checks, or substitute a sentinel string for non-finite inputs before they reach a logger call.
- Switch the affected appender's layout from JsonTemplateLayout to a layout whose output already handles or escapes the non-finite case, such as the Jackson-based JsonLayout (which exposes JsonWriteFeature.WRITE_NAN_AS_STRINGS) or a non-JSON layout like PatternLayout.
- Leverage a commercial support partner like HeroDevs for post-EOL security support through Never-Ending Support (NES) for Apache Log4j 2.
Credits
- Ap4sh (Samy Medjahed) (finder)
- Ethicxz (Eliott Laurie) (finder)
- Piotr P. Karwasz (ppkarwasz) (fixer)