🛡️ CVE-2026-48824 — mailpit

🟡 CVSS 5.3 — Medium ✅ No Known Exploit CWE-770 NVD
5.3
CVSS Score
0 Low4 Medium7 High9 Critical10

Description

Mailpit: Sibling-endpoint memory-exhaustion DoS via unbounded JSON body on /api/v1/messages, /api/v1/tags, and /api/v1/message/{id}/release (incomplete fix of GHSA-fpxj-m5q8-fphw)

Summary

The fix for GHSA-fpxj-m5q8-fphw (CVE-2026-45710, "Mailpit: Set a default 50MB p/m limit to prevent DoS via unlimited SMTP DATA and /api/v1/send body sizes") wrapped only POST /api/v1/send with http.MaxBytesReader. The four other Mailpit JSON-body API endpoints PUT /api/v1/messages (SetReadStatus), DELETE /api/v1/messages (DeleteMessages), PUT /api/v1/tags (SetMessageTags), and POST /api/v1/message/{id}/release (ReleaseMessage) still call json.NewDecoder(r.Body) directly with no body-size cap and remain reachable unauthenticated in the default docker run axllent/mailpit:latest deploy. An unauthenticated remote attacker can post a multi-million-element IDs slice and drive RSS from ~25 MiB baseline to ~450 MiB per 16 MB request body. Repeating across multiple connections accumulates the same per-request amplification per process.

Affected versions

  • Mailpit at HEAD 67a7ca83ff759082d2b86dda07eb5bb3dad404e0 (v1.30.0, 2026-05-14).
  • All versions <= v1.30.0 (the release that shipped the GHSA-fpxj fix). Versions < v1.30.0 are vulnerable to the original GHSA-fpxj on /api/v1/send; version v1.30.0 carries the sibling-endpoint gap described here.

Privilege required

None in default deploy (no --ui-auth, no --smtp-auth). The four endpoints share the same middleWareFunc wrapper as the original GHSA-fpxj target, so the same default-no-auth threat model applies. With --ui-auth=user:pass configured, the same primitive is post-auth — still useful since UI-auth Mailpit deployments commonly run on internal ops subnets where one stolen UI credential pivots into an RSS-exhaustion vector against the same host.

The incomplete fix

Commit 136bdde ("Security: Set a default 50MB p/m limit to prevent DoS via unlimited SMTP DATA and /api/v1/send body sizes (GHSA-fpxj-m5q8-fphw)", 2026-05-12) added the MaxBytesReader wrap in exactly one place:

```go

// server/apiv1/send.go:45-48

if config.MaxMessageSize > 0 {

r.Body = http.MaxBytesReader(w, r.Body, int64(config.MaxMessageSize)*1024*1024)

}

decoder := json.NewDecoder(r.Body)

```

The sibling JSON-body handlers were not updated. Side-by-side at HEAD 67a7ca8:

| File | Function | MaxBytesReader? | Unauth in default deploy? |

|---|---|---|---|

| server/apiv1/send.go:45-48 (SendMessageHandler) | POST /api/v1/send | YES (50 MB) | YES (via sendAPIAuthMiddleware falling back to middleWareFunc) |

| server/apiv1/messages.go:107 (SetReadStatus) | PUT /api/v1/messages | NO | YES |

| server/apiv1/messages.go:187 (DeleteMessages) | DELETE /api/v1/messages | NO | YES |

| server/apiv1/tags.go:54 (SetMessageTags) | PUT /api/v1/tags | NO | YES |

| server/apiv1/release.go:55 (ReleaseMessage) | POST /api/v1/message/{id}/release | NO | YES |

The four sibling handlers all share the shape:

```go

// server/apiv1/messages.go:107-115 (SetReadStatus)

decoder := json.NewDecoder(r.Body)

var data struct {

Read bool

IDs []string

Search string

}

err := decoder.Decode(&data)

```

No MaxBytesReader, no body-size cap, no r.Header.Get("Content-Length") check. The json.NewDecoder streams the body but each "x" element materialises as a separate Go string plus slice-header overhead, so the unmarshalled []string slice for IDs grows roughly linearly with attacker payload size.

Vulnerable code

server/apiv1/messages.go:107:

```go

func SetReadStatus(w http.ResponseWriter, r *http.Request) {

decoder := json.NewDecoder(r.Body)

var data struct {

Read bool

IDs []string

Search string

}

err := decoder.Decode(&data)

if err != nil {

httpError(w, err.Error())

return

}

// ...

```

Three other handlers (DeleteMessages, SetMessageTags, ReleaseMessage) match the same shape.

Reachability chain (default deploy)

```

Listen() # config/config.go HTTPListen = "[::]:8025"

HTTP server # server/server.go:177-186

middleWareFunc(apiv1.SetReadStatus) # server/server.go:178 — auth bypassed when UICredentials == nil

SetReadStatus # server/apiv1/messages.go:87

json.NewDecoder(r.Body).Decode(&data) # no MaxBytesReader; allocates 4M Go strings + slice for {"IDs":["x",...]}

RSS grows ~28x relative to payload size

```

config/config.go's MaxMessageSize field (added by 136bdde) exists and is parsed from --max-message-size (default 50 MB), but it is checked only in server/apiv1/send.go. The four sibling handlers never consult it.

Reproduction (E2E against axllent/mailpit:latest v1.30.0)

```bash

# 1) start mailpit with defaults (no --ui-auth, no --smtp-auth)

docker run --name mailpit-test -d -p 18025:8025 a

How this vulnerability can be exploited

This issue can be reached over the network, attack complexity is low, an attacker needs no privileges on the target. No user interaction is required. The scope is unchanged, so the impact stays within the vulnerable component. Rated impact: confidentiality none, integrity none, availability low.

Weakness class

CVE-2026-48824 is classified as CWE-770: Allocation of Resources Without Limits. Resources are allocated on request with no cap, so a client can exhaust them.

Affected software

CVE-2026-48824 is recorded against 2 packages.

  • github.com/axllent/mailpit
  • mailpit (fixed in 1.30.1)

Timeline and source

Published on 1 July 2026 and last revised on 7 July 2026. No public exploit is currently recorded for this entry. Record sourced from NVD.

References

github.com (Web)
github.com (Package)

Details

Severity Medium
CVSS Score 5.3
CVSS Vector CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L
CWE CWE-770
Public Exploit ✅ No
Source NVD
Published 2026-07-01
Updated 2026-08-12
Modified 2026-07-07
Fix URL N/A

Affected Packages

Software From version Fixed in
github.com/axllent/mailpit
mailpit 1.30.1

Similar Threats

Vulnerability Monitoring

Track new vulnerabilities in mailpit

CVE-2026-48824 is rated CVSS 5.3 Medium. BotEraser monitors your WordPress installation and notifies you when software you use appears in our vulnerability database.

Set Up Free Alerts →

No credit card required  ·  Results in minutes

ⓘ Data Notice: The information presented above has been compiled from publicly available internet sources. Boteraser aggregates this data solely for informational purposes and does not independently classify, evaluate, or endorse any findings about the vulnerabilities listed. The accuracy and completeness of this information is the sole responsibility of the original publishers. Boteraser and its operators accept no liability for any decisions made based on this data.