Sep 3, 2026·7 min read·11 visits
Unauthenticated remote attackers can crash Mailpit servers by transmitting email attachments containing compressed images with extremely large logical dimensions, triggering out-of-memory errors during thumbnail generation.
Mailpit decodes attacker-supplied image attachments into a full raster before checking decoded dimensions, pixel count, or memory use in the GET /api/v1/message/{id}/part/{partID}/thumb endpoint. This allows remote, unauthenticated attackers to trigger unconstrained memory allocation and cause a Denial of Service (DoS) via resource exhaustion.
Mailpit is an email testing tool and developer-focused API, designed to capture outgoing SMTP traffic and display it inside a local web interface. The application features a dedicated API endpoint at /api/v1/message/{id}/part/{partID}/thumb that automatically constructs JPEG thumbnail previews of incoming image attachments. This endpoint dynamically scales the target attachment down to a uniform 180 by 120 pixels layout to facilitate UI rendering.\n\nThe attack surface is exposed via Mailpit's SMTP server port and its subsequent JSON API interface. Because Mailpit typically runs in local development or test environments without authentication, any network-adjacent or remote client can transmit arbitrary emails with nested attachments. When the Mailpit backend receives an attachment labeled with a MIME type of image/*, it processes the raw content through its thumbnail generation pathway.\n\nThe vulnerability arises because the server performs complete in-memory rasterization of incoming images before executing any boundary checks or verifying structural properties. This design permits an unauthenticated attacker to inject a crafted payload that triggers significant memory allocations during the decompression phase. The flaw falls under the categories of CWE-400 (Uncontrolled Resource Consumption) and CWE-770 (Allocation of Resources Without Limits or Throttling).
The root cause of this vulnerability lies in the sequence of operations executed within the Mailpit thumbnail generation pipeline. When a request hits the thumbnail endpoint, the server retrieves the raw attachment bytes and attempts to decompress them into a standard image representation. The server relies on the github.com/disintegration/imaging library to read and process the underlying binary data.\n\nTo scale an image down to the required 180 by 120 pixel footprint, the application first invokes imaging.Decode(). This library call processes the source image stream and inflates the compressed pixel matrix into a full uncompressed raster structure in heap memory. This decompression behavior is standard across traditional image formats, where compressed formats such as PNG, JPEG, and GIF must be decoded into raw RGBA or NRGBA pixel representations.\n\nThe critical flaw is that Mailpit does not assess the declared width and height of the image prior to performing this full rasterization step. Compressed images, specifically formats using compression algorithms like DEFLATE or LZW, can encode massive dimensional attributes within a highly compact disk size. A tiny input file containing only tens of kilobytes can claim dimensions of 30,000 pixels by 30,000 pixels.\n\nWhen the Go runtime processes a 30,000 by 30,000 pixel image, it must allocate space for every individual pixel. At 4 bytes per RGBA pixel, the total memory required for the raster buffer is calculated as 30,000 multiplied by 30,000 multiplied by 4, which equates to exactly 3.6 gigabytes of RAM. Because this massive allocation occurs eagerly before the server performs any downscaling or validation checks, the process rapidly exhausts the host system's memory boundaries.
In the vulnerable implementation, the thumbnail handler in server/apiv1/thumbnails.go retrieved raw binary bytes from storage and loaded them into a memory buffer. This buffer was passed directly to the decoding function without any initial inspection or size constraints.\n\ngo\n// Vulnerable Implementation\nbuf := bytes.NewBuffer(a.Content)\n// The system decodes the entire image into a raw raster format\nimg, err := imaging.Decode(buf, imaging.AutoOrientation(true))\nif err != nil {\n // Error handling\n}\n\n\nThe patched version modifies this execution path by inserting an inspection layer. By utilizing image.DecodeConfig(), the application parses only the file's header information to retrieve the width and height parameters without allocating memory for the pixel matrix.\n\ngo\n// Patched Implementation in v1.30.4\n// We establish a strict limit of 20,000,000 pixels (approx. 80MB memory budget)\nconst maxDecodedPixels int64 = 20_000_000\n\n// Inspect the image configuration without allocating the underlying raster\nif cfg, _, cfgErr := image.DecodeConfig(bytes.NewReader(a.Content)); cfgErr == nil {\n // Cast the dimensions to 64-bit integers to prevent integer overflow exploits\n if int64(cfg.Width)*int64(cfg.Height) > maxDecodedPixels {\n logger.Log().Warnf("[image] rejected oversized image dimensions %dx%d", cfg.Width, cfg.Height)\n blankImage(a, w)\n return\n }\n}\n\nbuf := bytes.NewReader(a.Content)\nimg, err := imaging.Decode(buf, imaging.AutoOrientation(true))\n\n\nmermaid\ngraph LR\n A["Incoming Attachment"] --> B["image.DecodeConfig()"]\n B --> C{"Pixels > 20M?"}\n C -- "Yes" --> D["Reject & Return blankImage()"]\n C -- "No" --> E["imaging.Decode()"]\n E --> F["imaging.Fill(180x120)"]\n F --> G["Serve Thumbnail"]\n
Exploitation of this vulnerability requires two main steps: injecting a compressed image with extreme logical dimensions and forcing the server to generate a thumbnail. An attacker can perform these actions remotely and without authentication.\n\nThe attacker first crafts a valid PNG file that contains an empty or solid-color canvas. The pixel dimensions are configured to large numbers, such as 30,000 pixels on each side. Because the pixels are homogeneous, the resulting image compresses to a minimal size under 100 kilobytes, allowing it to bypass standard email message size limits.\n\nNext, the attacker transmits this image as an email attachment to Mailpit's SMTP port, which typically listens on port 1025. Once the email is processed, the attachment is written to storage. The vulnerability can then be triggered either by a user viewing the email through the web UI, which initiates an API request, or by the attacker querying the /api/v1/message/{id}/part/{partID}/thumb endpoint directly.\n\nThe server responds to this request by executing the vulnerable thumbnail generation logic. The Go runtime attempts to allocate the calculated 3.6 gigabytes of heap memory. On systems with constrained resources, such as Docker containers with limits under 1 gigabyte, the kernel's Out-Of-Memory (OOM) killer immediately terminates the Mailpit process, resulting in a complete denial of service.
The primary security consequence of CVE-2026-67446 is a localized Denial of Service (DoS) affecting the availability of the Mailpit instance. Because Mailpit is an open SMTP relay designed for testing, any client with access to the network can trigger this behavior remotely. No pre-existing credentials or session tokens are required to complete the attack chain.\n\nThe impact is classified as low under the CVSS framework because the service does not leak confidential data or permit unauthorized system modification. However, in environments where Mailpit is used as a critical component of automated testing pipelines or CI/CD workflows, the abrupt termination of the process can disrupt build schedules and block development tasks.\n\nFurthermore, because the Mailpit web interface automatically triggers the /thumb endpoint for any displayed message with image attachments, viewing the inbox serves as a stored vector. An administrator or developer opening the interface is forced to send the crash request, turning a passive email attachment into an active client-initiated crash sequence.
To resolve this vulnerability, deploy Mailpit version 1.30.4 or higher. The updated software implements a strict 20 megapixel validation check on incoming image attachments before allocating raw image buffers.\n\nWhile this mitigation resolves the primary exploitation path, security teams should evaluate the potential bypasses. The patch uses image.DecodeConfig to identify dimensions, which returns an error on heavily corrupted or malformed images. If a malformed image bypasses DecodeConfig but is still processed by the full Decode method, resource allocation issues may persist.\n\nAdditionally, the current logic does not limit concurrent decoding requests. A distributed attack containing multiple unique 19-megapixel images could still exhaust heap space in memory-restricted containers. Therefore, running Mailpit in an isolated container with auto-restart policies and limited API exposure remains a recommended defensive strategy.
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 | < v1.30.4 | v1.30.4 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-400, CWE-770 |
| Attack Vector | Network (AV:N) |
| CVSS Score | 5.3 (Medium) |
| Exploit Status | Proof of Concept |
| Impact | Denial of Service (DoS) |
| KEV Status | Not Listed |
The product does not properly control the allocation and maintenance of a limited resource, enabling an actor to influence the amount of resources consumed, eventually leading to the exhaustion of available resources.
An LDAP injection vulnerability exists in the centraldogma-server-auth-shiro module of LY Corporation Central Dogma before version 0.84.0. The search logic dynamically constructs LDAP search filters by interpolating user-provided usernames without escaping RFC 4515 metacharacters. Unauthenticated remote attackers can leverage this flaw to bypass authentication, enumerate directory hierarchies, and access unauthorized resources.
CVE-2026-11746 is a critical vulnerability in Central Dogma Server prior to version 0.84.0, where an embedded ZooKeeper replication secret silently falls back to a publicly known, hard-coded default string ('ch4n63m3'). Remote attackers with access to the replication network can authenticate as legitimate cluster peers, potentially leading to unauthorized data exposure, state manipulation, or complete cluster takeover.
A logical verification flaw in ZITADEL's external JWT Identity Provider validation allows attackers to bypass session expiration checks. If an incoming JWT lacks the 'exp' claim, the system skips validation entirely, creating an indefinitely valid session. This issue has been addressed in versions 3.4.12 and 4.15.2.
CVE-2026-59149 identifies a directory traversal vulnerability in `@mockoon/commons-server`, the backend mock-server library powering the Mockoon application. The flaw occurs in the path containment validation logic used during raw file response generation. An unauthenticated attacker can exploit this weakness to retrieve arbitrary files from sibling directories sharing a common prefix with the designated static base directory.
An in-depth analysis of CVE-2026-59148, a high-severity flaw in Mockoon where unauthenticated administrative endpoints and a wildcard Cross-Origin Resource Sharing (CORS) policy allow remote execution, state poisoning, and credential theft.
An improper authentication vulnerability (CWE-287) in ZITADEL's external identity provider handler before version 4.15.3 allows remote attackers to perform complete account takeover. When auto-linking by email is enabled, ZITADEL verifies that the local target account has a verified email address but fails to verify if the external provider confirmed ownership of that same email. Attackers can exploit this by registering an unverified account with a victim's email address on a permissive external provider, leading to unauthorized account binding and persistent access.