Presentation
Contao serves its resized images on a single route, /assets/images/{path}, whose parameter accepts any value.
HDW Sec found that the controller resolves the supplied path without checking that the result stayed inside the image directory, letting an unauthenticated visitor read files outside it and learn the layout of the installation.
Issue(s)
- The controller joins the user-supplied path onto the image directory with
Path::join(), a function that resolves..segments along the way, then serves the resulting file. - The check that would confirm the resolved path is still under the base directory is missing.
Path::isBasePath(), which does exactly that, is called five lines further down the same call chain for an unrelated purpose. - A literal
../is normalised by the web server before routing, so it never reaches the controller. Encoded as%2e%2e, it crosses intact and is only resolved atPath::join()time, too late to be refused. - Reads are limited to extensions declared as images, so no configuration files, PHP source or database credentials. The practical value is reconnaissance.
- Requesting a file that does not exist makes the controller print the resolved path in its 404 message, which discloses the absolute path of the installation.
- Apache and nginx are both affected; nginx additionally accepts the encoded slash
%2f, which Apache refuses by default.
References
- GitHub advisory: GHSA-mrvp-7wmx-5m4h
- Fixed in Contao 5.3.50 and 5.7.12, published 2026-08-25. No CVE assigned as of publication.