highCVSS 8.2Vulnerability

CVE-2026-48788

### Summary The remark42 image proxy fetches an arbitrary remote URL and re-serves the response from remark42's own origin. The download path decides whether the fetched resource is an image by looking only at the `Content-Type` header the remote server claims — it never inspects the actual bytes. The serving path then derives the response `Content-Type` by sniffing those bytes with `http.DetectContentType`. An attacker hosts a URL that sets `Content-Type` to `image/png` but returns an HTML/JavaScript body: * the download check sees `image/png` → accepts it; * the serve path sniffs the body → emits `Content-Type: text/html`; * the browser renders attacker HTML/JS as a document in remark42's origin. ### Details #### Downloader `backend/app/rest/proxy/image.go` — `downloadImage()`, lines 189-206: ```go contentType := resp.Header.Get("Content-Type") if !strings.HasPrefix(contentType, "image/") { return nil, fmt.Errorf("invalid content type %s", contentType) } maxSize := 5 * 1024 * 1024 // 5MB default if p.ImageService != nil && p.ImageService.MaxSize > 0 { maxSize = p.ImageService.MaxSize } lr := io.LimitReader(resp.Body, int64(maxSize)+1) imgData, err := io.ReadAll(lr) if err != nil { return nil, fmt.Errorf("unable to read image body: %w", err) } if len(imgData) > maxSize { return nil, fmt.Errorf("image is too large") } return imgData, nil // <-- bytes never validated, returned as-is ``` Send `Content-Type: image/png` and the check passes regardless of what the body actually contains. #### Server `backend/app/rest/proxy/image.go` — `Handler()`, line 131: ```go w.Header().Add("Content-Type", p.ImageService.ImgContentType(img)) _, err = io.Copy(w, bytes.NewReader(img)) ``` `backend/app/store/image/image.go` — `ImgContentType()`, lines 242-249: ```go func (s *Service) ImgContentType(img []byte) string { contentType := http.DetectContentType(img) if contentType == "application/octet-stream" { return "image/*" }

Properties

severity
high
summary
Remark42: Cross-Site Scripting (XSS) on /api/v1/img via content-type spoofing
epss_score
0.00247
cvss_score
8.2
ghsa_published
2026-06-26T19:26:43Z
source_url
https://github.com/advisories/GHSA-4c8j-mgm4-qqvp
ghsa_updated
2026-06-26T19:26:45Z
ghsa_id
GHSA-4c8j-mgm4-qqvp
cve_id
CVE-2026-48788
cvss_vector
CVSS:3.0/AV:N/AC:L/PR:N/UI:R/S:C/C:H/I:L/A:N
is_ghsa_only
false
epss_percentile
0.16

Related Entities (6)

ENRICHED_BY (1)

[Source]FIRST EPSS

VULNERABLE_TO (1)

[Software]go/github.com/umputun/remark42

AFFECTS (1)

[Software]go/github.com/umputun/remark42

HAS_WEAKNESS (2)

[Weakness]Interpretation Conflict
[Weakness]Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')

REPORTED_BY (1)

[Source]GitHub Advisory Database

Explore deeper with Ninja Signal's threat intelligence graph

CVE-2026-48788 (CVSS 8.2) — Ninja Signal Threat Intelligence | Ninja Signal