Close stored XSS in feedback upload/preview
fix(star-rating): close stored XSS in feedback upload/preview
Close stored XSS in feedback upload/previewae899f-fix-close-stored-xss-in-feedback-upload-cve-2026-44977fixclose stored xss feedback upload preview
Committed by ar2rsawseen
commit message
fix(star-rating): close stored XSS in feedback upload/preview
The /i/feedback/upload + /feedback/preview/* pair stored the client-
supplied MIME and reflected it back as Content-Type, letting an app
admin plant active HTML/JS served from the dashboard origin. A
higher-privileged viewer's same-origin XHR would then surface
countlyGlobal auth/csrf tokens to the attacker.
Fixes layered defense-in-depth:
- Sniff magic bytes server-side at upload; reject anything not in
the PNG/JPEG/GIF/WebP allowlist instead of trusting myfile.type.
- Re-derive Content-Type from sniffed bytes at preview time so any
pre-existing payload also can't be served as text/html.
- Add X-Content-Type-Options: nosniff, Content-Security-Policy:
"sandbox; default-src 'none'", and Content-Disposition: inline on
the preview response. The sandbox directive forces the response
into an opaque origin so even a payload that did execute could
not read /dashboard via same-origin XHR.
- Restrict accepted upload names to the global feedback_logo or
feedback_logo<24-char-hex-app-id>, and apply the same charset
check on the preview path component.
- Split authorization: the global logo now requires actual global
admin (not any app admin via global_plugins), and per-app logos
require admin on the specific app id encoded in the filename
(not whichever app id the request happens to carry).Editor assessment
This commit patches CVE-2026-44977. Exemplary. The body explains the vulnerability end to end: stored client MIME reflected as Content-Type, active HTML/JS served from the dashboard origin, and same-origin XHR exposing countlyGlobal auth/CSRF tokens. It then lays out five layered defenses - magic-byte sniffing, Content-Type re-derivation, nosniff plus sandbox CSP, filename charset restrictions, and split authorization - each with a reason. Subject and scope are precise. Style-wise the header and star-rating scope are precise and the body is a well-separated defense list; no formal improvement is needed.