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.
The endpoint:
src/controllers/AssetsController.php:1115-1123actionIcon(string $extension) calls Assets::iconPath($extension) and returns sendFile($path, ...).In Assets::iconPath():
extension:
src/helpers/Assets.php:906-909file_exists($path) is true, path is returned immediately:
src/helpers/Assets.php:910-912Validation exists in Assets::iconSvg():
preg_match('/^\w+$/', $extension)src/helpers/Assets.php:927-931However, 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().
{
"cwe_ids": [
"CWE-22"
],
"github_reviewed": true,
"github_reviewed_at": "2026-07-09T13:44:06Z",
"nvd_published_at": null,
"severity": "LOW"
}