Mailpit has a Server-Side Request Forgery (SSRF) via HTML Check API
Date: 2026-01
Affected: go/github.com/axllent/mailpit
Attack vector: ssrf
Category: vulnerability-disclosure
Severity: Medium
CVE: CVE-2026-23829
CVE-2026-23845
CWE: CWE-150
CWE-918
CWE-93
CVSS: 5.8 (CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:L/I:N/A:N)

### Server-Side Request Forgery (SSRF) via HTML Check CSS Download The HTML Check feature (`/api/v1/message/{ID}/html-check`) is designed to analyze HTML emails for compatibility. During this process, the `inlineRemoteCSS()` function automatically downloads CSS files from external `<link rel="stylesheet" href="...">` tags to inline them for testing. #### Affected Components - **Primary File:** `internal/htmlcheck/css.go` (lines 132-207) - **API Endpoint:** `/api/v1/message/{ID}/html-check` - **Handler:** `server/apiv1/other.go` (lines 38-75) - **Vulnerable Functions:** - `inlineRemoteCSS()` - line 132 - `downloadToBytes()` - line 193 - `isURL()` - line 221 #### Technical Details **1. Insufficient URL Validation (`isURL()` function):** ```go // internal/htmlcheck/css.go:221-224 func isURL(str string) bool { u, err := url.Parse(str) return err == nil && (u.Scheme == "http" || u.Scheme == "https") && u.Host != "" } ``` **2. Unrestricted Download (`downloadToBytes()` function):** ```go // internal/htmlcheck/css.go:193-207 func downloadToBytes(url string) ([]byte, error) { client := http.Client{ Timeout: 5 * time.Second, } // Get the link response data resp, err := client.Get(url) // ⚠️ VULNERABLE - No IP validation if err != nil { return nil, err } defer func() { _ = resp.Body.Close() }() if resp.StatusCode != 200 { err := fmt.Errorf("error downloading %s", url) return nil, err }


Mitigations:

Architectural layers (MAESTRO):