mediumCVSS 4.8Vulnerability

GHSA-69hx-63pv-f8f4

## Summary The file upload endpoint validates Content-Type using only the client-supplied multipart header, with no server-side content inspection or file extension validation. Combined with an unauthenticated static file server that determines Content-Type from file extension, this allows an admin to upload HTML/SVG files containing JavaScript that execute in the application's origin when visited by any user. Additionally, `image/svg+xml` is in the default allowed types, enabling stored XSS via SVG without any Content-Type spoofing. ## Details The upload handler at `internal/service/file/file.go:85-87` validates file type using only the multipart `Content-Type` header: ```go contentType := file.Header.Get("Content-Type") // client-controlled if !isAllowedType(contentType, config.Config().Upload.AllowedTypes) { return commonModel.FileDto{}, errors.New(commonModel.FILE_TYPE_NOT_ALLOWED) } ``` `isAllowedType` at `file.go:836-843` performs exact string matching — no magic byte detection, no extension validation: ```go func isAllowedType(contentType string, allowedTypes []string) bool { for _, allowed := range allowedTypes { if contentType == allowed { return true } } return false } ``` The original file extension is preserved in the storage key by `RandomKeyGenerator` at `internal/storage/keygen.go:41`: ```go ext := strings.ToLower(filepath.Ext(strings.TrimSpace(originalFilename))) ``` All locally stored files are served publicly without authentication at `internal/router/modules.go:51`: ```go ctx.Engine.Static("api/files", root) ``` This `gin.Static` call is registered directly on the engine, outside any authentication middleware group. Go's `http.ServeFile` (used internally by `gin.Static`) determines the response `Content-Type` using `mime.TypeByExtension`, so `.html` files are served as `text/html` and `.svg` files as `image/svg+xml`. No `X-Content-Type-Options: nosniff` or `Content-Security-Policy` headers ar

Properties

ghsa_id
GHSA-69hx-63pv-f8f4
severity
medium
summary
Ech0 has Stored XSS via SVG Upload and Content-Type Validation Bypass in File Upload
cvss_score
4.8
cve_id
GHSA-69hx-63pv-f8f4
cvss_vector
CVSS:3.1/AV:N/AC:L/PR:H/UI:R/S:C/C:L/I:L/A:N
is_ghsa_only
true
ghsa_published
2026-04-10T19:50:01Z
source_url
https://github.com/advisories/GHSA-69hx-63pv-f8f4
ghsa_updated
2026-04-10T19:50:02Z

Related Entities (4)

VULNERABLE_TO (1)

[Software]go/github.com/lin-snow/Ech0

AFFECTS (1)

[Software]go/github.com/lin-snow/Ech0

HAS_WEAKNESS (1)

[Weakness]Unrestricted Upload of File with Dangerous Type

REPORTED_BY (1)

[Source]GitHub Advisory Database

Explore deeper with Ninja Signal's threat intelligence graph

GHSA-69hx-63pv-f8f4 (CVSS 4.8) — Ninja Signal Threat Intelligence | Ninja Signal