Sep 9, 2026·6 min read·3 visits
Unauthenticated remote attackers can inject unescaped Unicode line separators into HTTP headers, forcing Unicode-aware downstream log parsers to split records and forge false logging entries in morgan versions < 1.12.0.
An incomplete fix vulnerability (CVE-2026-15603) in the morgan HTTP request logger middleware for Node.js allows unauthenticated remote attackers to forge log entries. The flaw arises because the escaping mechanism does not neutralize Unicode line separator characters, enabling attackers to inject payloads that trick downstream log processors into splitting single log records into multiple logical entries.
The standard Express.js HTTP request logging middleware, morgan, relies on internal token serializers to output connection data. When processing incoming client requests, the middleware collects variables such as IP addresses, request paths, headers, and authenticated usernames. If these variables are printed without proper sanitation, raw data can corrupt the log output format.
This vulnerability, tracked as CVE-2026-15603, belongs to the log forging class (CWE-117). It represents an incomplete validation patch for a previous vulnerability, CVE-2026-5078, which resolved ASCII control character injection but overlooked specific Unicode characters. Consequently, unauthenticated remote attackers can inject specific Unicode line breaks to split log entries and construct spoofed system logs.
The attack surface exists on any HTTP endpoint utilizing the morgan middleware where user-controlled values (such as Basic Authentication usernames) are logged. This issue does not require specific authorization to exploit, exposing applications to untrusted remote network payloads.
The root cause lies in the selective character blacklisting within the internal escaping routine of morgan. While version 1.11.0 successfully sanitized standard C0 control codes, backslashes, and delete characters, it did not recognize non-ASCII Unicode line terminators. Specifically, characters like Next Line (U+0085), Line Separator (U+2028), and Paragraph Separator (U+2029) were left untouched in the raw output stream.
According to RFC 7230 and RFC 9110, the U+0085 character is technically valid within HTTP header fields as obsolete text. Node.js's standard HTTP parser processes and forwards these headers without validation failures, allowing them to reach the logging pipeline. When morgan writes these unescaped bytes, they are appended directly to the output medium.
Modern log ingestion engines, terminal viewers, and SIEM parsers are highly compliant with the Unicode Standard. These tools parse U+0085, U+2028, and U+2029 as physical newline boundaries. When the output stream is read, a single request entry containing these characters is interpreted as multiple distinct logical records.
To comprehend the vulnerability, analyze the regular expression used in the vulnerable version 1.11.0. The escapeLogField function used a strict regex targeting C0 controls and backslashes:
// Vulnerable implementation in morgan v1.11.0
function escapeLogField (value) {
if (value == null) return undefined
// eslint-disable-next-line no-control-regex
return String(value).replace(/[\u0000-\u001f\u007f\\]/g, function (ch) {
switch (ch) {
case '\\': return '\\\\'
case '\b': return '\\b'
// Other standard C0 ASCII escapes omitted
}
})
}The patch introduced in version 1.12.0 corrected this regex by expanding the range to include C1 control characters (\u007f-\u009f) as well as the explicit separators \u2028 and \u2029. This blocks the injection vector completely:
// Patched implementation in morgan v1.12.0
function escapeLogField (value) {
if (value == null) return undefined
// eslint-disable-next-line no-control-regex
return String(value).replace(/[\u0000-\u001f\u007f-\u009f\u2028\u2029\\]/g, function (ch) {
switch (ch) {
case '\\': return '\\\\'
case '\b': return '\\b'
// Safely escapes Unicode characters preventing log boundaries
}
})
}Furthermore, the maintainers addressed systemic vulnerabilities in the token handling architecture. In previous versions, each logging token was individually responsible for escaping output. The patched version enforces a global wrapping boundary on all registered tokens, ensuring automatic escaping even if third-party components omit sanitization:
// Architectural wrapper added in v1.12.0
function token (name, fn) {
morgan[name] = function tokenValue () {
var value = fn.apply(this, arguments)
return typeof value === 'string' ? escapeLogField(value) : value
}
return this
}Exploiting this flaw requires an unauthenticated attacker to supply a crafted HTTP request header to a vulnerable server. The attack typically targets fields that are automatically extracted by log tokens, such as the Authorization header decoded by the :remote-user token. By structuring the username field appropriately, an attacker can inject custom records.
An attacker constructs a username containing the Next Line (U+0085) byte sequence, followed by an arbitrary string formatted to look like a standard log. For example, the string might contain a fabricated loopback IP, a successful authentication event, and a mock timestamp. This payload is encoded in Base64 and sent inside the standard Authorization header.
When morgan processes the request, it outputs the unescaped payload directly to stdout. Downstream aggregators, such as Fluentd or Logstash, identify the U+0085 sequence as a newline character. As a result, the aggregator splits the single output line, creating a truncated log for the attacker's actual connection, and a completely separate, forged log representing the injected payload.
No specialized toolsets are required to execute this exploit. Standard command-line clients like curl can transmit the required payload directly to any exposed endpoint on the target system.
The primary impact of this vulnerability is the compromise of log integrity. If malicious actors can write arbitrary lines to application logs, they can mask exploitation activities or spoof system behavior. This interferes directly with security auditing and post-incident investigation processes.
This technique aligns with MITRE ATT&CK Defense Evasion tactics, specifically Indicator Removal on Host (T1070). Attackers can obfuscate their presence by splitting logs to make automated warning messages appear associated with benign loopback actions. Additionally, Stored Data Manipulation (T1565.001) can trigger false alerts, causing operational disruptions.
The vulnerability is rated with a CVSS base score of 5.3 (Medium). While the exploit complexity is low and privileges are not required, the direct security boundaries of the target server are not violated. The impact is isolated entirely to the logging ecosystem and downstream ingestion layers.
Remediation requires upgrading the morgan dependency to version 1.12.0 or later. This version enforces complete output neutralization for all registered logging tokens. Administrators can execute the upgrade using package managers to update the dependency tree.
npm install morgan@1.12.0If patching cannot be performed immediately, a temporary mitigation can be implemented using intermediate middleware. A request preprocessing middleware can inspect and sanitize incoming headers before they are processed by the logger. This code must explicitly strip or replace characters in the C1 and Unicode separator ranges:
app.use((req, res, next) => {
for (const header in req.headers) {
if (typeof req.headers[header] === 'string') {
req.headers[header] = req.headers[header].replace(/[\u0080-\u009f\u2028\u2029]/g, '');
}
}
next();
});Additionally, firewalls and API gateways can be configured to drop requests containing these characters. Deploying regular expression signatures targeting [\x80-\x9f\u2028\u2029] within HTTP headers effectively mitigates remote exploitation attempts at the perimeter.
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:N| Product | Affected Versions | Fixed Version |
|---|---|---|
morgan OpenJS Foundation | < 1.12.0 | 1.12.0 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-117 |
| Attack Vector | Network (AV:N) |
| CVSS v3.1 | 5.3 (Medium) |
| EPSS Score | 0.00235 (14.34th percentile) |
| Impact | Log Forging & Injection (Integrity Loss) |
| Exploit Status | Proof of Concept (PoC) available |
| KEV Status | Not listed |
The software does not neutralize or incorrectly neutralizes output that is written to logs, allowing an attacker to forge log entries or inject malicious content.
A high-severity namespace injection vulnerability in both the MongoDB Client Library for PHP (mongodb/mongodb) and the native PHP C Extension (ext-mongodb) allows unauthenticated remote attackers to bypass logical database separation and execute database commands inside unauthorized storage compartments via dot (".") and null byte ("\0") injection.
A critical vulnerability (CVE-2026-84452) in the Windows ML CLI (winml-cli) HTTP server component allows unauthenticated remote code execution via permissive CORS and lack of request validation.
A high-severity denial of service vulnerability in the Node.js middleware 'multer' allows unauthenticated remote attackers to exhaust CPU resources and freeze applications. By submitting small, specially crafted 'multipart/form-data' requests containing large array indices alongside conflicting parameter keys, attackers force synchronous execution loops over up to 4.2 billion elements within the underlying 'append-field' library.
CVE-2026-77063 details a security flaw in multer, the standard multipart/form-data handler for Node.js, where asynchronous file filters introduce a race condition. This condition causes the library to miss file size limitation events, resulting in the silent acceptance of truncated files.
A resource consumption vulnerability exists in the multer library version 2.2.0 when utilizing the disk storage engine. When a remote client aborts or truncates an in-progress file upload, multer removes the partial file from the disk but fails to properly close the active write stream. This behavior leaves the underlying file descriptor open in the operating system, allowing a remote attacker to systematically exhaust the server's file descriptor limits and trigger a Denial of Service.
CVE-2026-77078 is a critical denial of service vulnerability in the multer Node.js package, allowing unauthenticated remote attackers to crash the runtime process using a single crafted multipart/form-data HTTP payload.