Craft CMS has authenticated path traversal in `assets/icon`, allowing local `.svg` file read
Published 9 Jul 2026 · Updated 6 Aug 2026
Affected packages
- Affected
- >=4.0.0-RC1 <4.17.7
- Fixed in
- 4.17.7
composer require craftcms/cms:^4.17.7- Affected
- >=5.0.0-RC1 <5.9.13
- Fixed in
- 5.9.13
composer require craftcms/cms:^5.9.13Details
Summary
An authenticated path traversal in assets/icon allows local SVG file read by passing traversal sequences in the extension parameter. The issue is caused by file existence checks happening before extension validation.
Details
The endpoint:
src/controllers/AssetsController.php:1115-1123actionIcon(string $extension)callsAssets::iconPath($extension)and returnssendFile($path, ...).
In Assets::iconPath():
- Path is built from user-controlled
extension: src/helpers/Assets.php:906-909- If
file_exists($path)is true, path is returned immediately: src/helpers/Assets.php:910-912
Validation exists in Assets::iconSvg():
preg_match('/^\w+$/', $extension)src/helpers/Assets.php:927-931
However, that validation is only reached if iconPath() does not find a file.
So traversal payloads that resolve to existing .svg files bypass validation and are served by sendFile().
Impact
- Authenticated users can read local .svg files accessible to the application process.
References
- https://github.com/craftcms/cms/commit/30f5f1a8d6edf0f3a00be72c42c78d9dc7d72d5c
Is GHSA-c43v-4cr8-6mvp in any of your client repos?
Checking one package by hand is fine. Checking it across forty client projects is not. NPMscan reads the lockfiles in every GitHub repo you pick, finds each project with an affected craftcms/cms, and gives you the command that fixes it.
References
- Linkgithub.com/craftcms/cms/security/advisories/GHSA-c43v-4cr8-6mvp
- Advisorynvd.nist.gov/vuln/detail/CVE-2026-56394
- Linkgithub.com/craftcms/cms/commit/30f5f1a8d6edf0f3a00be72c42c78d9dc7d72d5c
- Packagegithub.com/craftcms/cms
- Linkwww.vulncheck.com/advisories/craft-cms-authenticated-path-traversal-in-assets-icon-extension-parameter
Advisory data from OSV.dev (opens OSV.dev in a new tab), refreshed daily.