Skip to main content
Press slash or control plus K to focus the search. Use the arrow keys to navigate results and press enter to open a threat.
Reconnecting to live updates…
EPSS 0.3%top 82%

CVE-2026-45709: CWE-918: Server-Side Request Forgery (SSRF) in axllent mailpit

0
Medium
Published: 07/20/2026 (07/20/2026, 14:37:00 UTC)
Source: CVE Database V5
Vendor/Project: axllent
Product: mailpit

Description

## Summary The fix for GHSA-6jxm-fv7w-rw5j (CVE-2026-23845, "Server-Side Request Forgery (SSRF) via HTML Check API"), shipped in mailpit `v1.28.3`, hardened `internal/htmlcheck/css.go::downloadCSSToBytes` with a 5MB size cap, a `text/css` content-type check, login-info stripping in `isValidURL`, and an opt-in `--block-remote-css-and-fonts` config flag — but **did not add the IP-filtering dialer that the same codebase already uses on the two sister SSRF endpoints** (the proxy handler and link-check). At HEAD `8bc966e61834a24c48b4465da418f75e73be0afd` (2026-05-06), `internal/htmlcheck/css.go::newSafeHTTPClient` is mis-named — it builds an `http.Client` whose `Transport.DialContext` calls `net.Dialer.DialContext` directly with no IP allowlisting. As a result, the SSRF originally reported by Bao Anh Phan still permits the server to dial: - loopback (`127.0.0.0/8`, `::1`), - private (`10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16`, `fc00::/7`), - link-local incl. **cloud IMDS** (`169.254.0.0/16`, especially `169.254.169.254`), - CGNAT (`100.64.0.0/10`), - and any other reserved/multicast range, — provided the target replies with `HTTP/200` and a content-type beginning with `text/css`. With redirect-following (`CheckRedirect` allows redirects to any `isValidURL` URL with no IP filter), an attacker-controlled public site can redirect mailpit's request into the private network without ever appearing in the email's HTML. In the default mailpit deploy (no UI auth, no SMTP auth, port 1025/8025 exposed), this is an unauthenticated, network-reachable SSRF triggered by sending an HTML email and then issuing one HTTP `GET` to `/api/v1/message/{id}/html-check`. ## Affected versions - `internal/htmlcheck/css.go` at HEAD `8bc966e61834a24c48b4465da418f75e73be0afd` (2026-05-06). - All versions `>= v1.28.3` (the version that shipped the GHSA-6jxm fix). Versions `<= v1.28.2` are vulnerable to the original GHSA-6jxm; versions `>= v1.28.3` carry the still-vulnerable variant described here. ## The incomplete fix The original GHSA-6jxm fix added size+content-type+login-info hardening to `downloadCSSToBytes`. But the dialer it uses still has no `safeDialContext`. The companion `linkcheck` and `proxy` handlers in the same codebase have all-three protections: size cap, content-type/redirect filter, **AND** a `safeDialContext` that runs `tools.IsInternalIP(ip.IP)` per resolved address — same pattern the htmlcheck dialer should adopt. Side-by-side at HEAD `8bc966e`: | File | Function | `safeDialContext` (IP filter)? | TOCTOU-safe (dial-by-IP)? | |---|---|---|---| | `internal/linkcheck/status.go::safeDialContext` line 140-163 | dial check | YES | YES (resolved IP joined with port) | | `server/handlers/proxy.go::safeDialContext` line 393-415 | dial check | YES | YES | | `internal/htmlcheck/css.go::newSafeHTTPClient` line 275-310 | dial check | **NO** | n/a | The mis-named `newSafeHTTPClient` reads: ```go // internal/htmlcheck/css.go:275-310 func newSafeHTTPClient() *http.Client { dialer := &net.Dialer{ Timeout: 5 * time.Second, KeepAlive: 30 * time.Second, } tr := &http.Transport{ Proxy: nil, DialContext: func(ctx context.Context, network, address string) (net.Conn, error) { return dialer.DialContext(ctx, network, address) // no IP filter }, ... } client := &http.Client{ Transport: tr, Timeout: 15 * time.Second, CheckRedirect: func(req *http.Request, via []*http.Request) error { if len(via) >= 3 { return errors.New("too many redirects") } if !isValidURL(req.URL.String()) { return errors.New("invalid redirect URL") } return nil }, } return client } ``` `isValidURL` only rejects non-http(s) and userinfo URLs — it does NOT reject internal IPs. Compare `linkcheck/status.go::safeDialContext`: ```go ips, err := net.DefaultResolver.LookupIPAddr(ctx, host) ... if !config.AllowInternalHTTPRequests { for _, ip := range ips { if tools.IsInternalIP(ip.IP) { return nil, fmt.Errorf("blocked request to %s (%s): private/reserved address", host, ip) } } } return dialer.DialContext(ctx, network, net.JoinHostPort(ips[0].IP.String(), port)) ``` That's the protection htmlcheck is missing. ## Reachability chain (default deploy) ``` Listen() # config/config.go:36 SMTPListen = "[::]:1025" ↓ SMTP server # internal/smtpd/main.go:222-249 AuthRequired: false, AuthHandler: nil ↓ attacker injects HTML body with <link rel="stylesheet" href="...attacker.com/redirect.css"> ↓ storage.Store(...) ↓ Listen() # server/server.go HTTPListen ↓ attacker sends GET /api/v1/message/{id}/html-check apiv1.HTMLCheck # server/apiv1/other.go:18 ↓ no UI auth in default deploy (auth.UICredentials == nil) htmlcheck.RunTests(msg.HTML)

CVSS v3.1

Score 5.8medium

Attack Vector
Network
Attack Complexity
Low
Privileges Required
None
User Interaction
None
Scope
Changed
Confidentiality
None
Integrity
Low
Availability
None
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:N/I:L/A:N

Affected software

GitHub Actionsmore threats →ai
axllent/mailpit
pkg:github/axllent/mailpit
Affected versions
<1.30.0

Run on your own infrastructure? Check whether these packages are installed with threat-finder — our free open-source scanner.

AI-Powered Analysis

Machine-generated threat intelligence

AILast updated: 07/20/2026, 15:43:01 UTC

Technical Analysis

Mailpit's HTML Check API prior to version 1.30.0 uses an HTTP client that lacks IP allowlisting when fetching CSS resources, allowing SSRF attacks. Although a size cap and content-type checks were added in version 1.28.3, the client still permits requests to loopback, private, link-local, and reserved IP ranges if the response is HTTP 200 with a 'text/css' content-type. Redirects are followed without IP filtering, enabling an attacker-controlled public site to redirect requests into internal networks invisibly. The vulnerability is exploitable without authentication by sending a malicious HTML email and then calling the /api/v1/message/{id}/html-check endpoint. The fix in version 1.30.0 updates the HTTP client to include IP allowlisting, mitigating the SSRF risk.

Potential Impact

An unauthenticated attacker can exploit this SSRF vulnerability to make the mailpit server send HTTP requests to internal or private network addresses, potentially accessing internal services or resources not otherwise exposed. The vulnerability does not directly disclose data but can be used to interact with internal systems, causing information leakage or indirect impact. The CVSS score is 5.8 (medium severity) with network attack vector, low attack complexity, no privileges required, no user interaction, scope changed, no confidentiality impact, limited integrity impact, and no availability impact.

Mitigation Recommendations

Version 1.30.0 of mailpit contains an updated fix that adds IP allowlisting to the HTTP client used in the HTML Check API, effectively mitigating this SSRF vulnerability. Users should upgrade to mailpit version 1.30.0 or later to remediate this issue. No other official remediation or temporary fixes are documented. Patch status is not explicitly confirmed beyond the mention of version 1.30.0 containing the fix; users should verify with the vendor advisory for the latest guidance.

Pro Console: star threats, build custom feeds, automate alerts via Slack, email & webhooks.Upgrade to Pro

Technical Details

Data Version
5.2
Assigner Short Name
GitHub_M
Date Reserved
2026-05-13T04:38:01.166Z
Cvss Version
3.1
State
PUBLISHED
Remediation Level
null

Threat ID: 6a5e3e5d2a4a8d5989464d97

Added to database: 07/20/2026, 15:27:25 UTC

Last enriched: 07/20/2026, 15:43:01 UTC

Last updated: 09/03/2026, 22:52:12 UTC

Views: 83

Community Reviews

0 reviews

Crowdsource mitigation strategies, share intel context, and vote on the most helpful responses. Sign in to add your voice and help keep defenders ahead.

Sort by
Loading community insights…

Want to contribute mitigation steps or threat intel context? Sign in or create an account to join the community discussion.

Actions

PRO

Updates to AI analysis require Pro Console access. Upgrade inside Console → Billing.

Please log in to the Console to use AI analysis features.

Need more coverage?

Upgrade to Pro Console for AI refresh and higher limits.

For incident response and remediation, OffSeq services can help resolve threats faster.

Latest Threats

Breach by OffSeqOFFSEQFRIENDS — 25% OFF

Check if your credentials are on the dark web

Instant breach scanning across billions of leaked records. Free tier available.

Scan now
OffSeq TrainingCredly Certified

Lead Pen Test Professional

Technical5-day eLearningPECB Accredited
View courses