mediumCVSS 5.4Vulnerability

GHSA-whqh-9pq5-c7r3

## Summary The `SvgSanitizer::decodeAllEntities()` method limits recursive entity decoding to 5 iterations. By wrapping each character of `javascript` in an `href` attribute value with 5 levels of `&amp;` encoding around numeric HTML entities (e.g., `&amp;amp;amp;amp;amp;#106;` for `j`), an attacker can bypass both `isSafe()` detection and `sanitize()` removal. The uploaded SVG is served from the application origin with `image/svg+xml` content type, and the browser's XML parser fully decodes the remaining `&#NNN;` entities, resulting in a clickable `javascript:` link that executes arbitrary JavaScript. ## Details **Root cause:** `decodeAllEntities()` at `phpmyfaq/src/phpMyFAQ/Helper/SvgSanitizer.php:223-249` limits entity decoding to `maxIterations=5`. Each iteration: (1) decodes `&#NNN;` numeric entities, (2) decodes `&#xHH;` hex entities, (3) calls `html_entity_decode()` which resolves one level of `&amp;` → `&`. With 5 levels of `&amp;` wrapping, all 5 iterations are consumed unwinding the `&amp;` nesting, leaving the final `&#NNN;` numeric entities unresolved. **Code path:** 1. Authenticated user with `FAQ_EDIT` permission uploads SVG via `POST /admin/api/content/images` (`ImageController::upload()` at line 39) 2. File extension is `svg` → `SvgSanitizer::isSafe()` called (line 114) 3. `isSafe()` calls `decodeAllEntities()` — 5 iterations resolve `&amp;` nesting but leave `&#106;&#97;...` (numeric entities for `javascript`) 4. Pattern matching at line 47 (`/href\s*=\s*["\'][\s]*javascript\s*:/i`) does **not** match `&#106;&#97;...` 5. `isSafe()` returns **true** — file saved **without any sanitization** 6. SVG served directly by web server from `content/user/images/` with `image/svg+xml` MIME type 7. Browser's XML parser decodes `&#106;` → `j`, `&#97;` → `a`, etc., reconstructing `javascript:alert(document.domain)` 8. User clicks the SVG link → JavaScript executes in the phpMyFAQ origin The bypass is even simpler than initially described — no `<script>` dec

Properties

ghsa_id
GHSA-whqh-9pq5-c7r3
severity
medium
summary
phpMyFAQ has a SVG Sanitizer Entity Decoding Depth Limit Bypass Leading to Stored XSS
cvss_score
5.4
cve_id
GHSA-whqh-9pq5-c7r3
cvss_vector
CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:C/C:L/I:L/A:N
is_ghsa_only
true
ghsa_published
2026-05-06T20:18:48Z
source_url
https://github.com/advisories/GHSA-whqh-9pq5-c7r3
ghsa_updated
2026-05-06T20:18:50Z

Related Entities (6)

VULNERABLE_TO (2)

[Software]composer/phpMyFAQ/phpMyFAQ
[Software]composer/thorsten/phpMyFAQ

AFFECTS (2)

[Software]composer/thorsten/phpMyFAQ
[Software]composer/phpMyFAQ/phpMyFAQ

HAS_WEAKNESS (1)

[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

GHSA-whqh-9pq5-c7r3 (CVSS 5.4) — Ninja Signal Threat Intelligence | Ninja Signal