Threats tagged 'ghsa-4ffr-jq9g-5ffx'
1 threat
Most recently published first
| Severity | CVSS | Threat | Source | Published | Score and star |
|---|---|---|---|---|---|
| Medium | 5.9 | Medium5.9GCVE Database ## Summary Nodemailer's SMTP client applies four regular expressions to a peer's EHLO response to detect the supported SASL mechanisms. Each pattern uses an alternation with two overlapping whitespace-matching sub-patterns, which produces quadratic (O(n^2)) backtracking whenever the mechanism name is absent from the line. A malicious or MITM SMTP server that answers EHLO with `250-AUTH` followed by a long whitespace-only run and a non-matching token blocks the Node.js event loop for tens of seconds to hours during a pre-authentication handshake. No authentication to the target SMTP server is required, and any application that connects to an attacker-influenced host is affected. ## Root Cause Each of the four AUTH mechanism regexes in `SMTPConnection._actionEHLO` contains the sub-pattern `(?:(\s+|=)[^\n]*\s+|\s+|=)` before the mechanism literal. `[^\n]*` and the trailing `\s+` both match whitespace and can consume the same characters, so when the mechanism literal is absent, the regex engine must try every partition of the whitespace run between `[^\n]*` and `\s+` before failing. The four regexes run unconditionally on every EHLO response, with no length cap, no shape validation, and no early rejection before the engine enters the ambiguous alternation. ```text Component: nodemailer (npm), SMTP client Function: SMTPConnection._actionEHLO Location: src/smtp-connection/index.ts, lines 2162, 2167, 2172, 2177 Patterns: /[ -]AUTH(?:(\s+|=)[^\n]*\s+|\s+|=)PLAIN/i /[ -]AUTH(?:(\s+|=)[^\n]*\s+|\s+|=)LOGIN/i /[ -]AUTH(?:(\s+|=)[^\n]*\s+|\s+|=)CRAM-MD5/i /[ -]AUTH(?:(\s+|=)[^\n]*\s+|\s+|=)XOAUTH2/i ``` ## Impact Algorithmic-complexity denial of service against any Node.js process that opens an SMTP connection to an attacker-controlled or attacker-influenced host. Node.js is single threaded, so the process stalls entirely while the regex engine backtracks: no other requests are served, no timers fire, and the built-in socket timeout (10 minutes) cannot interrupt synchronous JavaScript. A 4,000-character whitespace run inside a single continuation line already blocks each regex for tens of seconds; the client bounds a response at 1 MB, which leaves headroom for blocking runs measured in hours across the four patterns. Two realistic attacker positions reach the sink pre-authentication: a hosted mailer that lets tenants configure their own SMTP server, and any network-adjacent attacker able to man-in-the-middle a cleartext SMTP connection (including before STARTTLS negotiation). ## Proof of Concept The PoC exercises the exact four regexes copied from `src/smtp-connection/index.ts` against a synthesized `250-AUTH<whitespace>NOMATCH` line, so no live SMTP server is needed to reproduce the timing. ```text Runtime: Node.js >= 20 Dependencies: none Invocation: node poc.js ``` ```javascript 'use strict'; const AUTH_REGEXES = [ /[ -]AUTH(?:(\s+|=)[^\n]*\s+|\s+|=)PLAIN/i, /[ -]AUTH(?:(\s+|=)[^\n]*\s+|\s+|=)LOGIN/i, /[ -]AUTH(?:(\s+|=)[^\n]*\s+|\s+|=)CRAM-MD5/i, /[ -]AUTH(?:(\s+|=)[^\n]*\s+|\s+|=)XOAUTH2/i, ]; function bench(n) { const line = '250-AUTH' + ' '.repeat(n) + 'NOMATCH'; const start = Date.now(); for (const re of AUTH_REGEXES) re.test(line); return Date.now() - start; } for (const n of [500, 1000, 2000, 3000]) { console.log(`n=${n} four-regex time=${bench(n)} ms`); } const control = '250-AUTH PLAIN LOGIN CRAM-MD5 XOAUTH2'; const t0 = Date.now(); for (const re of AUTH_REGEXES) re.test(control); console.log(`well-formed control four-regex time=${Date.now() - t0} ms`); ``` ```text n=500 four-regex time=914 ms n=1000 four-regex time=1348 ms n=2000 four-regex time=10558 ms n=3000 four-regex time=35251 ms well-formed control four-regex time=0 ms ``` Doubling the whitespace run multiplies the wall time by roughly four, which matches the expected O(n^2) growth. The well-formed control shows that a normal EHLO response is parsed in effectively zero time. ## Attack Chain 1. **Exposure:** The victim application, or any dependent that uses `nodemailer` to send mail, opens a TCP or TLS connection to an SMTP host the attacker controls. This happens automatically for multi-tenant mailers whose tenants configure their own outbound SMTP server, and for any client whose plaintext SMTP session can be intercepted by a network-adjacent attacker before STARTTLS negotiation. 2. **Control:** The attacker fully controls the bytes returned in response to `EHLO`. In particular, the attacker chooses the length and content of every `250-` continuation line up to the client's 1 MB response cap. 3. **Path:** Socket bytes are reassembled by `_onData`, decoded by `_processResponse`, and dispatched to `_actionEHLO`. On the first EHLO after the greeting (malicious server with no STARTTLS), on the second EHLO after a successful STARTTLS upgrade, or on the first EHLO when `ignoreTLS` is set, control reaches the AUTH detection block near the end of `_act | GCVE Database |
Page 1 of 1