GHSA-mrvp-7wmx-5m4h
Contao: Path traversal in the images controller
Packages
| Ecosystem | Package | Affected | Fixed in |
|---|---|---|---|
| Packagist | contao/core-bundle | >= 4.1.0, < 5.3.50 | 5.3.50 |
| Packagist | contao/core-bundle | >= 5.4.0-RC1, < 5.7.12 | 5.7.12 |
Details
As written in the advisory (Markdown source, shown as plain text).
`ImagesController` joins the user controlled `{path}` onto the configured image target directory with `Path::join()`, which canonicalises `..` segments, and never calls `Path::isBasePath()` to confirm the result stayed inside that directory. An unauthenticated GET with percent encoded dot segments therefore escapes the directory and the file is returned by `BinaryFileResponse`. Reads are bounded to the extensions in `contao.image.valid_extensions`, and paths below the upload directory fail for an unrelated reason, so this is reported as a missing boundary check rather than as a general arbitrary file read. Both Apache with the shipped `public/.htaccess` and nginx with the documented configuration are affected.
### Impact
Any unauthenticated visitor can read files that are deliberately kept outside the document root, anywhere under the project directory, as long as the name ends in one of `contao.image.valid_extensions` (`jpg`, `jpeg`, `gif`, `png`, `tif`, `tiff`, `bmp`, `svg`, `svgz`, `webp`). The route also acts as an existence oracle for arbitrary paths, and on a debug enabled instance the 404 message discloses the absolute filesystem path.
**Honesty caveat, stated because it lowers the severity.** The reporter could not use this to read protected member folders: every path below the upload directory returns 500 for the reason given under Details, so the practically reachable set is image typed files outside `files/`.
References
External links from the advisory. They lead to third-party sites.