Логотип exploitDog
Консоль
Логотип exploitDog

exploitDog

github логотип

GHSA-grm4-wm43-9jh5

Опубликовано: 06 авг. 2026
Источник: github
Github: Прошло ревью
CVSS3: 3.1

Описание

Contao: Possible path traversal in job download URIs

Summary

An authenticated backend user who can access one job can request an attachment identifier containing ../ segments and make the job attachment download endpoint read a file from another job directory inside var/job-attachments.

The controller authorizes only the jobUuid route parameter. The later attachment lookup joins that authorized job UUID with the attacker-controlled identifier, then passes the combined path to the virtual filesystem. VirtualFilesystem::resolve() canonicalizes the whole path and only rejects paths that escape the filesystem mount, so authorized-job/../victim-job/debug_log.csv becomes victim-job/debug_log.csv.

This is a cross-job authorization bypass for known job attachment paths. It is not a practical brute-force against unknown jobs because job directories are UUID v4 values.

Root Cause

JobsController::downloadJobAttachment() checks access to the route jobUuid before loading the attachment:

$job = $this->jobs->getByUuid($jobUuid); if (!$job || !$this->jobs->hasAccess($job)) { throw $this->createNotFoundException(); } $attachment = $this->jobs->getAttachment($jobUuid, $identifier);

Jobs::getAttachment() then resolves a path built from the authorized job UUID and the attacker-controlled identifier:

$fileItem = $this->jobAttachmentsStorage->get($this->getAttachmentIdentifier($job, $identifier));
return $job->getUuid().'/'.$identifier;

VirtualFilesystem::resolve() canonicalizes the combined path. It rejects absolute paths and paths that start with .., but it does not preserve the authorized job directory as a boundary:

$path = Path::canonicalize($location); if (str_starts_with($path, '..')) { throw new \OutOfBoundsException(...); } return Path::join($this->prefix, $path);

Therefore:

<authorized-job>/../<victim-job>/debug_log.csv

canonicalizes to:

<victim-job>/debug_log.csv

which remains inside the job-attachments filesystem mount and is accepted.

Recommended Fix

Treat the attachment identifier as a filename, not a path:

  • Reject /, \, NUL, and dot-segment components in identifier.
  • Add a route requirement that prevents slashes in {identifier} if nested attachment paths are not intended.
  • After resolving, assert the canonical relative path starts with <authorized-job-uuid>/ before returning a FilesystemItem.
  • Apply the same identifier validation in Jobs::addAttachment() so future producers/extensions cannot write outside the owning job directory.

Impact

A low-privileged backend user can read another job's attachment if they know or obtain the target job UUID and attachment filename. Built-in crawler jobs attach CSV logs such as debug_log.csv, broken-link-checker_log.csv, and search-index_log.csv, which can contain crawled URLs, referring URLs, tags, and error messages.

Пакеты

Наименование

contao/contao

composer
Затронутые версииВерсия исправления

>= 5.7.0, < 5.7.7

5.7.7

Наименование

contao/core-bundle

composer
Затронутые версииВерсия исправления

>= 5.7.0, < 5.7.7

5.7.7

EPSS

Процентиль: 11%
0.00209
Низкий

3.1 Low

CVSS3

Дефекты

CWE-22

Связанные уязвимости

CVSS3: 3.1
nvd
около 2 месяцев назад

Contao is an Open Source CMS. In versions 5.7.0 through 5.7.6, an authenticated backend user who can access one job can request an attachment identifier containing ../ segments and make the job attachment download endpoint read a file from another job directory inside var/job-attachments. The controller authorizes only the jobUuid route parameter. The later attachment lookup joins that authorized job UUID with the attacker-controlled identifier, then passes the combined path to the virtual filesystem. VirtualFilesystem::resolve() canonicalizes the whole path and only rejects paths that escape the filesystem mount, so authorized-job/../victim-job/debug_log.csv becomes victim-job/debug_log.csv. This is a cross-job authorization bypass for known job attachment paths. It is not a practical brute-force against unknown jobs because job directories are UUID v4 values.

EPSS

Процентиль: 11%
0.00209
Низкий

3.1 Low

CVSS3

Дефекты

CWE-22