CVEReports
CVEReports

Automated vulnerability intelligence platform. Comprehensive reports for high-severity CVEs generated by AI.

Product

  • Home
  • Sitemap
  • RSS Feed

Company

  • About
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 CVEReports. All rights reserved.

Made with love by Amit Schendel & Alon Barad



GHSA-268H-HP4C-CRQ3

GHSA-268h-hp4c-crq3: CRLF Injection via List-* Header Comments in Nodemailer

Alon Barad
Alon Barad
Software Engineer

Jun 15, 2026·8 min read·3 visits

Executive Summary (TL;DR)

A CRLF injection vulnerability in Nodemailer <= 8.0.8 allows remote attackers to inject arbitrary email headers by placing newline characters inside dynamic List-* header comments. This occurs because 'prepared' headers bypass Nodemailer's standard sanitization pipeline.

GHSA-268h-hp4c-crq3 is a Carriage Return Line Feed (CRLF) injection vulnerability in the Nodemailer npm package affecting versions up to and including 8.0.8. The library allows arbitrary email header injection when parsing user-controlled comments within list headers (such as List-Unsubscribe or List-ID). This occurs because list headers bypass standard validation by utilizing an internal 'prepared' flag, causing unsanitized newlines to be emitted directly into the outgoing RFC822 mail stream. This exploit allows remote attackers to inject custom, unauthorized mail headers, disrupting signature checks, bypassing filters, or spoofing parameters.

Vulnerability Overview

Nodemailer is an open-source library for Node.js applications that facilitates outbound email transmission via SMTP or transport streams. To support standard newsletter and list features, Nodemailer includes native parsing for List-* headers as defined in RFC 2369 and RFC 2919. These headers, such as List-Unsubscribe, List-Help, and List-ID, allow modern mail clients to display standardized administrative buttons (e.g., Unsubscribe) above the main message body.\n\nThe attack surface is exposed when applications dynamically populate list parameters with user-provided metadata, such as comment descriptors or user-specific unsubscribe configurations. While standard mail headers in Nodemailer undergo rigorous input sanitation to strip or normalize control sequences, list headers are handled by a specialized compilation pipeline. This pipeline flags the resulting values as trusted, pre-compiled payloads, effectively preventing downstream sanitation filters from executing validation routines on these parameters.\n\nIf an attacker can control the comment portion of a list header configuration (e.g., list.unsubscribe.comment or list.id.comment), they can inject Carriage Return (\r) and Line Feed (\n) sequences. These control sequences act as raw layout boundaries in the final RFC822 output stream. Because the message structure splits fields strictly based on CRLF boundaries, the parser treats the trailing portion of the comment as a standalone, root-level message header. This security flaw is classified as CWE-93 (Improper Neutralization of CRLF Sequences).

Root Cause Analysis

The root cause resides in the differential handling of headers inside the Nodemailer compiler core. Specifically, the vulnerability manifests when constructing list headers in lib/mailer/mail-message.js and subsequently generating the stream layout in lib/mime-node/index.js. Standard header fields undergo an escaping pipeline where literal raw control characters are converted into spaces or safely wrapped using RFC 2047 MIME encoding. In contrast, list headers are compiled via the internal helper _getListHeaders(this.data.list).\n\nDuring compilation in lib/mailer/mail-message.js (lines 241-296), each configured list entry is parsed into a structured header object. For instance, the compilation of the List-ID comment field checks if the parameter is plain text using mimeFuncs.isPlainText(comment). If this is evaluated as true, the parser wraps the comment in parentheses and embeds it into the header value directly. However, the evaluation relies solely on the characters falling within printable ASCII ranges and completely fails to neutralize or reject raw CRLF (\\r\\n) sequences.\n\nCrucially, when these list header structures are finalized, they are returned with a specifier configuration of { prepared: true, foldLines: true, value: ... }. The prepared attribute is an internal flag instructing Nodemailer's MIME layout generator to skip regular sanitization, parsing, and escaping processes under the assumption that the value was already normalized. In lib/mime-node/index.js (lines 323-351), the layout engine detects this flag and calls mimeFuncs.foldLines(key + ': ' + value) directly. The unsanitized payload, containing the raw CRLF sequences, is outputted into the outgoing RFC822 transport stream, executing the injection.

Code Analysis

To understand the vulnerable code path, we examine how the list headers are constructed in lib/mailer/mail-message.js before being passed to lib/mime-node/index.js. The vulnerable compilation logic for list headers is as follows:\n\njavascript\n// Vulnerable snippet in lib/mailer/mail-message.js\n// For list properties, headers are dynamically generated and marked as 'prepared'\nlet value = this._getListHeaders(this.data.list);\n\n// Inside _getListHeaders implementation:\nif (item.comment) {\n // The library only checks if the comment is plain text\n // but does not sanitize or strip actual CRLF characters\n if (mimeFuncs.isPlainText(item.comment)) {\n commentStr = '(' + item.comment + ')';\n } else {\n commentStr = mimeFuncs.encodeWord(item.comment);\n }\n}\n\n// The resulting compiled list headers are added with the prepared flag:\nthis.message.addHeader(listHeader.key, {\n prepared: true,\n foldLines: true,\n value: formattedValue + (commentStr ? ' ' + commentStr : '')\n});\n\n\nWhen the MIME generator in lib/mime-node/index.js processes headers, it checks the configuration of the incoming header object. Regular headers undergo strict sanitization, but prepared headers bypass validation completely, as illustrated below:\n\njavascript\n// Inside lib/mime-node/index.js\n_postProcessHeaders(headers) {\n // ...\n if (header.prepared) {\n // Security Bypass: No CRLF validation or sanitization is conducted\n // The raw string is folded and pushed directly to the header output block\n this._headers.push(mimeFuncs.foldLines(header.key + ': ' + header.value));\n } else {\n // Safe path: Sanitizes raw header strings to prevent boundary injection\n let sanitizedValue = this._sanitizeHeaderValue(header.value);\n this._headers.push(mimeFuncs.foldLines(header.key + ': ' + sanitizedValue));\n }\n // ...\n}\n\n\nThis implementation path demonstrates that the prepared attribute establishes an implicit trust boundary. Because Nodemailer treats internal helpers as secure components, any omission of validation in the upstream _getListHeaders function leads to an unmitigated injection path. The patch in version 8.0.9 addresses this by sanitizing CRLF sequences in _getListHeaders before compiling the comment into the final output value.

Exploitation Methodology

Exploiting GHSA-268h-hp4c-crq3 requires an application flow that passes dynamic user input into the comment fields of a list header configuration. The attacker inserts a Carriage Return (\r) and Line Feed (\n) sequence followed by the target header field they wish to inject. Since MIME messages rely on CRLF as structural delimiters between discrete headers, the injected CRLF sequences terminate the List-* header early and initiate a new header context.\n\nConsider an application that allows users to define custom list titles or unsubscribe notes, which are then passed to Nodemailer's sendMail parameters. An attacker can set the comment parameter to the following payload:\n\nmy-comment\\r\\nX-Injected-Header: InjectedValue\n\nWhen Nodemailer compiles the list header, it builds the string representation inside parentheses: (my-comment\\r\\nX-Injected-Header: InjectedValue). Because this is marked as prepared: true, the literal value is written directly to the output stream. The physical output sequence appears as:\n\nhttp\nList-Unsubscribe: <https://example.com/unsubscribe> (my-comment\r\nX-Injected-Header: InjectedValue)\r\n\n\nTo downstream SMTP servers and email clients, this payload is parsed as two distinct headers: a truncated List-Unsubscribe header and a standalone X-Injected-Header. The payload does not corrupt the remaining structure of the mail envelope, making the injection clean and difficult to detect without inspecting raw message sources. This bypass is highly reliable as it relies strictly on RFC822 layout parsers that are structurally bound to split headers on CRLF boundaries.

Impact Assessment

The impact of CRLF injection within an email rendering and delivery library is significant. First, an attacker can exploit this vulnerability to bypass spam and email security filter mechanisms. Many security appliances assess outbound or inbound email posture by evaluating structural headers. By injecting headers like X-Spam-Threshold, Precedence: bulk, or custom trust headers, attackers can systematically manipulate the spam classification scoring of their payloads, allowing phishing emails to reach the victim's inbox.\n\nSecond, the flaw can be leveraged for advanced social engineering and phishing attacks. Attackers can inject custom header fields such as Reply-To, Sender, or mail-client-specific priority configurations. This allows the attacker to alter the visually represented sender or reply destination in common mail applications, tricking recipients into sending sensitive information to unauthorized endpoints.\n\nThird, this injection can compromise cryptographic message integrity. Standard email signatures like DKIM (DomainKeys Identified Mail) sign specific headers or header structures to prove origin integrity. By injecting additional headers or altering existing ones, attackers can break DKIM signatures or cause downstream Mail Transfer Agents (MTAs) to discard or flag authentic mail as forged. If the injection contains multiple CRLF sequences, it can even prematurely terminate the header block, injecting arbitrary text or HTML into the message body itself.

Remediation and Defensive Countermeasures

To remediate this vulnerability, software developers must upgrade nodemailer to version 8.0.9 or higher. This release corrects the flaw by integrating sanitization steps within the list compiler, ensuring any list.*.comment option has carriage return and line feed characters neutralized or rejected prior to building the prepared header payload.\n\nIf an immediate upgrade of the package is not feasible due to regression risks or environment constraints, developers must implement input-validation wrappers to cleanse inputs before passing them to the Nodemailer parameters. A strict sanitization regex should be applied to any user-controlled comment inputs to strip out Carriage Return and Line Feed control characters. The following sanitization implementation is recommended for legacy deployments:\n\njavascript\nfunction sanitizeListComment(comment) {\n if (typeof comment !== 'string') {\n return comment;\n }\n // Strip carriage returns and line feeds to neutralize injection vector\n return comment.replace(/[\\r\\n]+/g, '');\n}\n\n// Implement within mail configuration flow\nconst mailOptions = {\n from: 'no-reply@example.com',\n to: 'user@example.com',\n subject: 'Unsubscribe Confirmation',\n list: {\n unsubscribe: {\n url: 'https://example.com/unsubscribe',\n comment: sanitizeListComment(req.body.userComment)\n }\n }\n};\n\n\nIn addition to local sanitization, security teams should configure Web Application Firewalls (WAFs) and application runtimes to inspect incoming request parameters for raw or URL-encoded carriage returns (%0D, %0A, \\r, \\n) targeting parameters destined for email construction modules. This multi-layered defense minimizes the likelihood of exploitation.

Technical Appendix

CVSS Score
5.4/ 10

Affected Systems

Applications running Nodemailer <= 8.0.8 utilizing dynamic List-* headers.

Affected Versions Detail

Product
Affected Versions
Fixed Version
nodemailer
nodemailer
<= 8.0.88.0.9
AttributeDetail
CWE IDCWE-93
Attack VectorNetwork (Remote)
CVSS Score5.4
Exploit Statuspoc
ImpactArbitrary Email Header Injection
Fixed Version8.0.9

MITRE ATT&CK Mapping

T1566Phishing
Initial Access
T1071Application Layer Protocol
Command and Control

Vulnerability Timeline

Vulnerability Discovered & Security Advisory Published
2026-06-15
Nodemailer v8.0.9 Patched Release Made Available
2026-06-15

References & Sources

  • [1]GitHub Security Advisory GHSA-268h-hp4c-crq3
  • [2]Nodemailer Code Repository

Attack Flow Diagram

Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.
Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.

More Reports

•7 minutes ago•CVE-2026-48525
5.3

CVE-2026-48525: Uncontrolled Resource Consumption in PyJWT Detached JWS Verification

PyJWT versions 2.8.0 through 2.12.1 are vulnerable to an unauthenticated Denial of Service (DoS) attack. When verifying detached JSON Web Signatures (JWS) using the unencoded-payload option (RFC 7797, b64=false), the library eagerly decodes the payload segment before verifying the header configuration or the cryptographic signature. This behavior enables a remote, unauthenticated attacker to inject an arbitrarily large payload segment, triggering excessive CPU and memory resource consumption prior to signature validation.

Alon Barad
Alon Barad
0 views•6 min read
•about 1 hour ago•GHSA-WQVQ-JVPQ-H66F
5.4

GHSA-WQVQ-JVPQ-H66F: Security Control Bypass in Nodemailer via Transport Serialization

Nodemailer prior to version 8.0.9 contains a security control bypass vulnerability. Transport-level configuration parameters designed to restrict local file system access and remote URL requests are not propagated to all content-resolution execution paths. This failure allows unauthorized local file inclusion and server-side request forgery when the application utilizes specific transports or processing flags.

Alon Barad
Alon Barad
2 views•6 min read
•about 2 hours ago•CVE-2026-48524
3.7

CVE-2026-48524: Remote Cache Eviction and Authentication Denial of Service in PyJWT

A logic flaw in PyJWT's PyJWKClient class allows remote unauthenticated attackers to trigger a complete authentication outage. By transmitting a volume of JWTs containing randomized, non-existent Key ID (kid) values, attackers force synchronous outbound JWKS resolution queries. When these queries fail or time out, a defect in the error cleanup code overwrites the local cache of valid signing keys with None, causing a denial of service.

Alon Barad
Alon Barad
4 views•8 min read
•about 3 hours ago•CVE-2026-49982
8.2

CVE-2026-49982: Path Traversal Bypass via Type Confusion in node-tmp

A high-severity type-confusion path traversal vulnerability (CVE-2026-49982 / GHSA-7c78-jf6q-g5cm) exists in the node-tmp package version 0.2.6. The vulnerability allows remote attackers to bypass path validation checks by passing non-string data types such as Arrays or duck-typed Objects into options like prefix, postfix, or template. Because the library relies on the .includes() method without verifying the input type, standard array checks evaluate differently than string checks. Downstream string coercion subsequently restores the traversal sequence, allowing files and directories to be created outside the designated temporary directory root. This can result in arbitrary file writes and potential local file execution depending on application context.

Amit Schendel
Amit Schendel
5 views•6 min read
•about 5 hours ago•CVE-2026-47347
5.3

CVE-2026-47347: Open Redirect Vulnerability in TYPO3 CMS GeneralUtility::sanitizeLocalUrl

CVE-2026-47347 is an open redirect vulnerability affecting multiple TYPO3 CMS versions. The issue resides in GeneralUtility::sanitizeLocalUrl, where an insufficient blocklist validation implementation fails to prevent browsers from normalizing malformed relative paths into external protocol-relative redirections. Attackers can exploit this to conduct phishing, session hijacking, or credential harvesting campaigns.

Alon Barad
Alon Barad
3 views•7 min read
•about 5 hours ago•CVE-2026-47349
5.3

CVE-2026-47349: Missing Authorization in TYPO3 CMS DataHandler Record Restoration

An authenticated backend user with access to the Recycler module in TYPO3 CMS can bypass write restrictions and restore soft-deleted records on pages or database tables they are not authorized to modify. This vulnerability resides in the core DataHandler class due to missing permission checks during 'undelete' operations.

Alon Barad
Alon Barad
3 views•7 min read