Sep 3, 2026·7 min read·3 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 information disclosure vulnerability in the SiYuan knowledge management system versions up to and including v3.7.2 allows remote unauthorized attackers to retrieve PDF annotations via the /api/asset/getFileAnnotation endpoint due to missing authorization checks.
CVE-2026-72807 is a second-order SQL injection vulnerability in SiYuan versions prior to v3.7.4. It resides in the dynamic evaluation of Attribute View (AV) template columns, which expose unsafe template functions. An attacker can exploit this by distributing a malicious SiYuan package that executes arbitrary SQL queries on the victim's local database.
An authorization bypass vulnerability in SiYuan prior to v3.7.4 allows unauthenticated remote attackers to access rows, block IDs, and custom attributes of password-protected documents via the attribute view rendering endpoint.
SiYuan Note versions before v3.7.4 fail to enforce publish-access checks on several block API endpoints. This vulnerability allows anonymous readers or authorized accounts with low-privileged roles to retrieve sensitive document titles, ancestor block content snippets, reference text, and path metadata for publish-forbidden or password-protected documents by supplying target block IDs.
SiYuan before version 3.7.4 contains an authentication bypass vulnerability within its graph visualization API endpoints, allowing unauthenticated remote attackers to extract sensitive node metadata and content from password-protected documents.
SiYuan Note versions prior to v3.7.4 contain an information disclosure vulnerability in the `/api/asset/resolveAssetPath` endpoint. This endpoint returns absolute backend filesystem paths unmodified to CheckAuth-only requests. Low-privileged users or unauthenticated readers under publish mode can exploit this to leak the local directory layout, operating system username, and overall host deployment structure.