
CVE-2026-34038: Authenticated Remote Command Injection in Coolify
This repository contains documentation and analysis for CVE-2026-34038, a critical command injection vulnerability in Coolify.
An authenticated remote command injection vulnerability (CWE-78) in Coolify allows users with application "write" permissions to achieve Remote Code Execution (RCE) and Exfiltrate sensitive environment variables (e.g., database credentials, API keys) via deployment logs, even if the build environment isolates the Docker socket.
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:Hwrite (to update configuration) and read:sensitive (to read exfiltrated data via logs).deploy permissions to trigger builds.dockerfile_location InjectionFile: app/Jobs/ApplicationDeploymentJob.php
Input lacks proper shell escaping or input validation, permitting direct command injection using metacharacters like ;, &&, and pipes.
// Lines 2976-2978: Traditional build with args
$build_command = $this->wrap_build_command_with_env_export(
"docker build {$this->buildTarget} --network {$this->destination->network} -f {$this->workdir}{$this->dockerfile_location} {$this->build_args} --progress plain -t $this->build_image_name {$this->workdir}"
);
// Lines 526: Also used in simple dockerfile deployment
executeInDocker($this->deployment_uuid, "echo '$dockerfile_base64' | base64 -d | tee {$this->workdir}{$this->dockerfile_location} > /dev/null"),
pre_deployment_command ExecutionFile: app/Jobs/ApplicationDeploymentJob.php (Lines 3882-3909)
While basic escaping is performed, the function naturally runs native shell commands, making it possible to dump data straight into build logs.
private function run_pre_deployment_command()
{
if (empty($this->application->pre_deployment_command)) {
return;
}
// ...
$cmd = "sh -c '".str_replace("'", "'\\''", $this->application->pre_deployment_command)."'";
$exec = "docker exec {$containerName} {$cmd}";
$this->execute_remote_command(
[
'command' => $exec,
'hidden' => true,
],
);
}
dockerfile_location Input (in ApplicationDeploymentJob.php):Validate the input using strict regular expressions and escape the shell argument:
if ($this->application->dockerfile_location) {
if (!preg_match('/^[a-zA-Z0-9._\-\/]+$/', $this->application->dockerfile_location)) {
throw new \RuntimeException("Invalid dockerfile_location: contains forbidden characters");
}
if (str_contains($this->application->dockerfile_location, '..')) {
throw new \RuntimeException("Invalid dockerfile_location: path traversal detected");
}
$this->dockerfile_location = escapeshellarg($this->application->dockerfile_location);
}
bootstrap/helpers/api.php):'dockerfile_location' => [
'string',
'nullable',
'regex:/^[a-zA-Z0-9._\-\/]+$/',
'max:255'
],
docker_compose_location.