CVE-2026-54511 is a high-severity (CVSS 8.6) CWE-93 vulnerability in @logtape/syslog. A fix is available for @logtape/syslog — see the affected versions and patch details below.
@logtape/syslog: syslog log injection via unescaped control characters and unvalidated SD-NAME keys
Exploitation Status
No confirmed exploitation observed yet
- CISA assesses this as automatable — exploitation doesn’t require manual, per-target effort, which raises the odds of mass scanning and opportunistic attacks.
- CISA’s own triage has not observed active exploitation or public proof-of-concept code for this CVE as of its last assessment.
Exploitation and automatability from CISA’s SSVC triage for CVE-2026-54511.
EPSS Exploitation Probability
Probability of exploitation in the next 30 days, from FIRST.org EPSS.
How urgent is this, really
CVE-2026-54511 by exploitation likelihood (EPSS) against impact (CVSS). Outside the shaded patch-first corner.
Where this sits among everything scored
Of 385,386 CVEs with a current EPSS score, this one falls in the < 10% band (highlighted). Counts from FIRST.org, log-scaled.
Real-World Exposure
How broadly this vulnerability is actually deployed: weekly install volume shows current usage, and reverse-dependency count shows how many other packages break if it stays unpatched.
@logtape/syslognpmDescription
@logtape/syslog contains two related output-encoding bugs in the structured data formatting code. Both only affect deployments with includeStructuredData: true, which is non-default.
1. Unescaped C0 control characters in structured data values
escapeStructuredDataValue() in packages/syslog/src/syslog.ts escapes \, ", and ] per RFC 5424 but does not escape newline (\n), carriage return (\r), or any other C0 control characters (U+0000–U+001F):
function escapeStructuredDataValue(value: string): string {
return value
.replace(/\\/g, "\\\\")
.replace(/"/g, '\\"')
.replace(/]/g, "\\]");
// \n, \r, and other C0 control characters are not escaped
}
TCP syslog commonly uses \n as a frame delimiter (RFC 6587, non-transparent framing). If an attacker-controlled value contains a literal newline, that newline terminates the current syslog frame. Bytes following the newline begin a new frame, and if they form a valid RFC 5424 header (<PRI>1 …), a downstream collector will accept them as a separate, authentic-looking syslog record.
2. Unvalidated SD-NAME keys
Structured data parameter keys are inserted into the message without validation or escaping:
elements.push(`${key}="${escapedValue}"`);
RFC 5424 defines SD-NAME as printable US-ASCII characters excluding =, ], ", and space, with a maximum length of 32. A key containing any of those characters, control characters, or exceeding the length limit will produce malformed structured data. If the key itself contains an embedded ], it can prematurely close the structured-data element.
In typical usage, property keys are developer-defined string literals and therefore safe. However, if an application forwards attacker-controlled keys as log properties—for example by spreading request headers or arbitrary metadata into a log record—this becomes a second injection path.
Proof of concept
The following Node.js snippet (no dependencies, no network required) demonstrates that the escaped value still contains a literal newline:
function escapeStructuredDataValue(value) {
return value
.replace(/\\/g, "\\\\")
.replace(/"/g, '\\"')
.replace(/]/g, "\\]");
}
const payload =
'normal\n<134>1 2026-01-01T00:00:00Z forged evil - - - INJECTED';
const result = escapeStructuredDataValue(payload);
console.log("Newline present after escape:", result.includes("\n")); // true
Tested with Node.js 22.17.1.
Impact
An attacker who controls log property values can:
- forge syslog records attributed to arbitrary hosts, applications, or process IDs;
- insert records with arbitrary severity or facility levels;
- obscure malicious activity by injecting misleading entries around legitimate ones;
- break downstream log parsers or SIEM correlation rules that rely on log integrity.
Affected downstream collectors include rsyslog, syslog-ng, Splunk, Elastic Stack, and any other system using RFC 6587 non-transparent framing.
Suggested fix
Structured data values
Escape all C0 control characters (U+0000–U+001F) in addition to \, ", and ]. RFC 5424 does not define an escape sequence for control characters in PARAM-VALUE; the most interoperable approach is to strip or replace them:
function escapeStructuredDataValue(value: string): string {
return value
.replace(/\\/g, "\\\\")
.replace(/"/g, '\\"')
.replace(/]/g, "\\]")
.replace(/[\x00-\x1f]/g, (c) =>
`\\x${c.charCodeAt(0).toString(16).padStart(2, "0")}`
);
}
Alternatively, strip them entirely: .replace(/[\x00-\x1f]/g, ""). The right choice depends on whether downstream consumers need some representation of the original value.
SD-NAME keys
Validate each key against the RFC 5424 SD-NAME grammar before including it. Keys that fail validation should be skipped or sanitized:
// SD-NAME: printable US-ASCII, excluding '=', ']', '"', SP; max 32 chars
const SD_NAME_RE = /^[!-<>-Z\\^-z|~]{1,32}$/;
for (const [key, value] of Object.entries(record.properties)) {
if (!SD_NAME_RE.test(key)) continue;
const escapedValue = escapeStructuredDataValue(String(value));
elements.push(`${key}="${escapedValue}"`);
}
Affected Packages
| Ecosystem | Package | Vulnerable range | Fix |
|---|---|---|---|
| 📦npm | @logtape/syslog | ≥ 2.1.0&&< 2.1.5 | 2.1.5npm install @logtape/syslog@2.1.5 |
| 📦npm | @logtape/syslog | ≥ 2.0.0&&< 2.0.14 | 2.0.14npm install @logtape/syslog@2.0.14 |
| 📦npm | @logtape/syslog | all versions | 1.3.11npm install @logtape/syslog@1.3.11 |
Detection & mitigation playbook
Open-source dependencyDetect
Scan your dependency tree (package-lock.json, pnpm-lock.yaml, requirements.txt, go.sum, etc.) for @logtape/syslog, including transitive dependencies — a direct dependency you never call can still pull in a vulnerable version.
Fix
Update @logtape/syslog to 2.1.5 or later, then make sure no transitive (indirect) dependency still pins the vulnerable range — O3 confirms CVE-2026-54511 is resolved across your whole dependency graph.
Workarounds
If you can't upgrade right away: gate or disable the affected feature, validate untrusted input at the boundary, and avoid passing attacker-controlled data into the vulnerable path. O3's runtime protection blocks exploitation in production as an interim safeguard until the upgrade lands.
Frequently Asked Questions
Is CVE-2026-54511 in your dependencies?
Find it across npm, including transitive dependencies.