{"id":"GHSA-2wwr-9x6f-88gp","title":"EasyAdminBundle has path traversal and reflected XSS in Flag and Icon Twig components","summary":"EasyAdminBundle has path traversal and reflected XSS in Flag and Icon Twig components","severity":"medium","cvss":5.3,"cwe":["CWE-22","CWE-73","CWE-79"],"vendor":"easycorp","product":"easycorp/easyadmin-bundle","ecosystem":"composer","affected":["easycorp/easyadmin-bundle >= 4.0.0, < 4.29.10","easycorp/easyadmin-bundle >= 5.0.0, < 5.0.10"],"patched":["easycorp/easyadmin-bundle 4.29.10","easycorp/easyadmin-bundle 5.0.10"],"published":"2026-07-01","updated":"2026-07-01","source":"GHSA","sourceUrl":"https://github.com/advisories/GHSA-2wwr-9x6f-88gp","references":[{"url":"https://github.com/EasyCorp/EasyAdminBundle/security/advisories/GHSA-2wwr-9x6f-88gp"},{"url":"https://github.com/advisories/GHSA-2wwr-9x6f-88gp"}],"tags":["ghsa","composer"],"ingestedAt":"2026-07-01T19:15:59.922Z","slug":"GHSA-2wwr-9x6f-88gp","body":"## Overview\n\nEasyAdminBundle ships two public Twig components — `<twig:ea:Flag countryCode=\"...\">` and `<twig:ea:Icon name=\"...\">` — that load SVG files from disk using a path built directly from a public component property, and then render the resulting markup with the Twig `|raw` filter.\n\nWhen an application binds either of those properties to data that is influenced by an end user, the lack of validation on the property value leads to two distinct issues:\n\n- Arbitrary `.svg` file disclosure (both components) — the property value is concatenated into a filesystem path without normalizing or constraining it, so `..` segments are preserved and resolved by PHP. Any file on the server whose absolute path ends in `.svg` (for example, user-uploaded SVG icons stored elsewhere on the host) can be read and embedded into the rendered page.\n- Reflected XSS in the admin UI (Flag component only) — when the requested flag file does not exist, the Flag component falls back to a hard-coded SVG string that interpolates the raw `countryCode` value twice, and the parent template renders that string with `|raw`. An attacker who controls `countryCode` can therefore inject arbitrary HTML/JavaScript that will execute inside the authenticated admin context that rendered the component.\n\nThe first-party usage shipped by EasyAdminBundle itself is not affected: the bundle only passes ISO 3166 alpha-2 codes validated through `Symfony\\Component\\Intl\\Countries` to the `Flag` component, and only hard-coded `internal:..` names or values previously set in PHP via `MenuItem::setIcon()` to the `Icon` component. The vulnerability is reachable only in third-party templates that pass attacker-controlled data into these properties.\n\n### Impact\n\nPath traversal is information disclosure bounded by the `.svg` extension; reflected XSS in Flag runs in the admin context and is therefore more sensitive but requires a vulnerable template wiring and user interaction.\n\n### Affected components\n\n- `EasyCorp\\Bundle\\EasyAdminBundle\\Twig\\Component\\Flag` — public Twig tag `<twig:ea:Flag>`, property `countryCode`.\n- `EasyCorp\\Bundle\\EasyAdminBundle\\Twig\\Component\\Icon` — public Twig tag `<twig:ea:Icon>`, property `name` when the value starts with the `internal:` prefix.\n\n### Credit\n\nEasyAdmin would like to thank Claude Mythos Preview (via Project Glasswing and The PHP Foundation) for reporting the issue and providing the fix.\n\n## Affected packages\n\n- `easycorp/easyadmin-bundle >= 4.0.0, < 4.29.10`\n- `easycorp/easyadmin-bundle >= 5.0.0, < 5.0.10`\n\n## Remediation\n\nUpgrade to a patched release:\n\n- `easycorp/easyadmin-bundle 4.29.10`\n- `easycorp/easyadmin-bundle 5.0.10`","depth":"sunlit","depthScore":29,"depthScoreParts":{"impact":29.2,"likelihood":0,"exploitation":0,"ransomware":0},"changes":[]}