CVE-2026-34594: Verified Reproduction
CVE-2026-34594: Coolify authenticated command injection in Destination Network Management
CVE-2026-34594 is verified against the affected target. Vulnerability class: Command Injection. This high reproduction includes runnable sandbox proof, artifacts, and a plain-text agent view under REPRO-2026-00245.
What Is CVE-2026-34594?
CVE-2026-34594 is a high-severity authenticated OS command injection (CWE-78) in Coolify's Destination Network Management feature, letting a user with destination-management permissions execute arbitrary commands as root on the Coolify-managed host. Pruva reproduced it (reproduction REPRO-2026-00245).
CVE-2026-34594 Severity & CVSS Score
CVE-2026-34594 is rated high severity, with a CVSS base score of 8.8 out of 10.
High — serious impact or readily exploitable. Prioritize remediation.
How to Reproduce CVE-2026-34594
pruva-verify REPRO-2026-00245 curl -O https://www.pruva.dev/api/v1/reproductions/REPRO-2026-00245/artifacts/bundle/repro/reproduction_steps.sh && chmod +x reproduction_steps.sh && ./reproduction_steps.sh Proof of Reproduction for CVE-2026-34594
- reached the target end-to-end
- full exploit chain demonstrated
- on the real production code path
- high confidence
- the upstream fix blocks the same trigger
Destination Network Management 'network' field = x;id > /tmp/coolify_net_pwned 2>&1 # (shell metacharacters ; > #)
- Authenticated POST /livewire/update driving destination.new.docker submit()
- StandaloneDocker::create(['network'=>...])
- StandaloneDocker::created boot event
- instant_remote_process(['docker network inspect <network> ...'],$server)
- SshMultiplexingHelper::generateSshCommand
- ssh root@server 'bash -se' << delim (unsanitized network executed by remote bash)
reproduction_steps.sh How the agent worked
Root Cause and Exploit Chain for CVE-2026-34594
Coolify (self-hosted PaaS, Laravel/Livewire application) before 4.0.0-beta.471
contains an authenticated command-injection vulnerability in the Destination
Network Management functionality. The network field of a Docker Destination
(App\Livewire\Destination\New\Docker and App\Livewire\Destination\Show) was
only validated as ['required','string'], so an authenticated user with
destination-management permissions could submit a value containing shell
metacharacters. That value is stored on the StandaloneDocker / SwarmDocker
model and later interpolated unsanitized into shell commands that Coolify
executes on the destination's server over SSH
(instant_remote_process() → SshMultiplexingHelper::generateSshCommand() →
ssh ... 'bash -se' << $delimiter). Because the network string becomes the
body of a here-doc fed to bash -se on the remote host, an attacker-controlled
network such as x;id > /tmp/pwned # results in arbitrary command execution
as root on the Coolify-managed server at the moment the destination is
created (the StandaloneDocker::created boot event) and again when it is
deleted.
- Package/component affected:
coollabsio/coolify— Destination Network Management (app/Livewire/Destination/New/Docker.php,app/Livewire/Destination/Show.php,app/Models/StandaloneDocker.php,app/Models/SwarmDocker.php, and every shell consumer of->destination->network:ApplicationDeploymentJob,DatabaseBackupJob,StartService,Initcommand,bootstrap/helpers/proxy.php). - Affected versions: Coolify
< 4.0.0-beta.471(verified on the official imageghcr.io/coollabsio/coolify:4.0.0-beta.470). - Risk level: High. Coolify executes SSH commands with the destination
server's user (default
root). The injected command runs with that privilege on the managed host, enabling full server compromise, access to the Docker socket, lateral movement, and exposure of all managed resources / secrets. Exploitation requires only an authenticated user who can create a destination (theStandaloneDockerPolicy::createcheck returnstruefor any authenticated user;createAnyResourcelikewise returnstrue).
Impact Parity
- Disclosed/claimed maximum impact: Authenticated command execution ("arbitrary command execution on the Coolify host") via the Destination Network Management network field.
- Reproduced impact from this run: Authenticated command execution as
rooton the destination server. The injectedidcommand wroteuid=0(root) gid=0(root) groups=0(root)to a marker file on the managed server, proving arbitrary command execution with root privileges through the authenticated web request. - Parity:
full— the claimed authenticated command injection was demonstrated end-to-end against the real product, and the fixed build rejects the same input with no execution.
Root Cause
The network attribute of a Docker Destination is attacker-controlled input
that flows into privileged shell commands without validation or escaping.
Vulnerable code path (beta.470):
app/Livewire/Destination/New/Docker.phpdeclares the field with only#[Validate(['required','string'])](no character whitelist), andsubmit()callsStandaloneDocker::create(['network' => $this->network, ...]).app/Models/StandaloneDocker.phpboot()registers astatic::createdhook that runs:
The network is interpolated directly into the command string.instant_remote_process([ "docker network inspect $newStandaloneDocker->network >/dev/null 2>&1 || docker network create --driver overlay --attachable $newStandaloneDocker->network >/dev/null", ], $server, false);instant_remote_process()builds an SSH command viaSshMultiplexingHelper::generateSshCommand(), which sends the command as the body of a here-doc tobash -seon the remote server:timeout <t> ssh ... 'root'@'<ip>' 'bash -se' << $delimiter <command containing the unsanitized network> $delimiterescapedUserAtHost()escapesuser@ip, but the command body (the network) is never escaped, so shell metacharacters innetworkare interpreted by the remotebash.;breaks out of thedocker network inspecttoken, the attacker command runs, and#comments out the rest of the line. The same unsanitized interpolation exists inDestination/Show.php::delete()and acrossApplicationDeploymentJob,DatabaseBackupJob,StartService,Init, andproxy.php.
Fix (PR #9228, released in 4.0.0-beta.471, commit
3d1b9f53a0aec74468be75675bcaaaed0fd41d46; release tag commit
914d7e0b50505bc1fd56c34974fca09ad354e92a):
- Adds
DOCKER_NETWORK_PATTERN = '/^[a-zA-Z0-9][a-zA-Z0-9._-]*$/'inapp/Support/ValidationPatterns.phpand applies it as aregexvalidation rule on thenetworkfield in both Livewire components. - Adds a
setNetworkAttribute()mutator onStandaloneDockerandSwarmDockerthat throwsInvalidArgumentExceptionfor names not matching the pattern. - Applies
escapeshellarg()to every shell usage of the network field.
Reproduction Steps
- Reference:
bundle/repro/reproduction_steps.sh(self-contained). - What the script does:
- Installs the
docker composev2 plugin if missing and pulls the official Coolify images (4.0.0-beta.470vulnerable,4.0.0-beta.471fixed) pluspostgres:15-alpine,redis:7-alpine,coolify-testing-host(an SSH-enabled target whoseauthorized_keysmatches a hardcoded key) andcoolify-realtime. - Brings up the real Coolify stack (Coolify Laravel app + Postgres + Redis +
Soketi + the SSH target) on a private Docker network, with
IS_WINDOWS_DOCKER_DESKTOP=trueso the seeded localhost server targetscoolify-testing-host. - Bootstraps an authenticated root user, the testing-host SSH private key,
and a server pointing at
coolify-testing-host(root, port 22). - From the
coolify-testing-hostcontainer, runs an authenticated Python client against the live Coolify web app (http://coolify:8080): logs in via Laravel Fortify, loads/server/{uuid}/destinations, extracts thedestination.new.dockerLivewire snapshot, and POSTs/livewire/updatesettingnetwork = "x;id > /tmp/coolify_net_pwned 2>&1 #"and callingsubmit(). - Repeats for the fixed image as a negative control.
- Installs the
- Expected evidence:
- Vulnerable build: the
StandaloneDocker::createdevent runs the SSH command with the injected network;/tmp/coolify_net_pwned*on the SSH target containsuid=0(root) gid=0(root) groups=0(root), and the Livewire response redirects to the newly created destination. - Fixed build: the request is rejected with
The network field format is invalid.(regex validation), no destination is created, and no marker file appears.
- Vulnerable build: the
Evidence
bundle/logs/reproduction_steps.log— full orchestrated run log.bundle/logs/stack_vulnerable.log,bundle/logs/setup_vulnerable.log— vulnerable stack bring-up and bootstrap.bundle/logs/vulnerable_attempt_1.log,bundle/logs/vulnerable_attempt_2.log— exploit output for the vulnerable build (Livewireredirectto/destination/<uuid>→ destination created).bundle/logs/vulnerable_marker_content.txt— captured marker content (uid=0(root) gid=0(root) groups=0(root)).bundle/logs/stack_fixed.log,bundle/logs/setup_fixed.log— fixed stack.bundle/logs/fixed_attempt_1.log,bundle/logs/fixed_attempt_2.log— exploit output for the fixed build (VALIDATION_BLOCKED+The network field format is invalid., no redirect, no marker).bundle/repro/runtime_manifest.json— runtime evidence manifest (entrypoint_kind=api_remote,service_started=true,healthcheck_passed=true,target_path_reached=true).
Key reproduced excerpts (from the interactive verification run):
- Vulnerable:
effects redirect=http://coolify:8080/destination/o1jvtyfefdzb8nxnyqv0lkd2;standalone_dockersrow withnetwork = x;id > /tmp/coolify_net_pwned 2>&1 #onserver_id=1; marker/tmp/coolify_net_pwned=uid=0(root) gid=0(root) groups=0(root). - Fixed:
effects redirect=None, response snippetThe network field format is invalid.; nostandalone_dockersrow with the malicious network; marker file absent.
Environment: official Coolify Docker images on the shared Docker daemon; the
authenticated HTTP client runs in the coolify-testing-host container
(reaches coolify:8080 over the coolifynet-repro bridge); command execution
is performed by Coolify over SSH (bash -se here-doc) from the coolify
container to coolify-testing-host as root.
Recommendations / Next Steps
- Upgrade to Coolify
>= 4.0.0-beta.471(PR #9228). The fix combines input validation (regex whitelist matching Docker network naming rules), a model mutator that rejects invalid names, andescapeshellarg()on every shell usage of the network field. - Defense-in-depth: audit every
instant_remote_process()/remote_process()call site for user-controlled interpolation; preferescapeshellarg()/escapeshellcmd()and validated whitelists for any field that becomes part of an SSH/Docker command string. Consider a shared helper that forbids raw string interpolation of model attributes into command strings. - Restrict destination-management permissions; do not expose the Coolify admin interface publicly.
Additional Notes
- Idempotency: the script tears the stack down (
docker compose down -v+ hard cleanup of the fixed container/volume/network names) before each build, andsetup.phpis idempotent (locates the root user by email, fixes the password hash, ensures a singlecoolify-testing-hostserver). Two attempts are run per build with distinct marker paths (hence distinct network strings) to avoid the(server_id, network)unique constraint. - The Docker daemon in this environment is on a separate host from the script
execution sandbox, so published host ports are not reachable from the
sandbox; the authenticated client therefore runs inside the
coolify-testing-hostcontainer and reaches Coolify over the private Docker network (http://coolify:8080). This is a genuine authenticated HTTP request to the running Coolify service; the command execution crosses a real SSH boundary from Coolify to the managed server. - No sanitizers (ASAN/UBSAN/etc.) are used; this is a real product-mode runtime proof. The negative control (fixed image) demonstrates the patch closes the injection without relying on sanitizer output.
CVE-2026-34594 Reproduction Transcript
The agent's step-by-step process — every tool call, every handoff, the moment the exploit fired.
Full session Replay every step — scrub the timeline or play it back.
Artifacts and Evidence for CVE-2026-34594
Scripts, logs, diffs, and output captured during the reproduction.
How to Fix CVE-2026-34594
FAQ: CVE-2026-34594
When does the CVE-2026-34594 command injection trigger?
Does exploiting CVE-2026-34594 require authentication?
How severe is CVE-2026-34594?
How can I reproduce CVE-2026-34594?
References for CVE-2026-34594
Authoritative sources for CVE-2026-34594 — official vulnerability databases and the upstream advisory. Pruva's reproduction verifies the issue firsthand; these are the primary records to corroborate it.