CVE-2026-72863 Overview
Dokploy is a free, self-hostable Platform as a Service (PaaS). Versions prior to 0.29.13 contain a broken access control flaw in the WebSocket handlers backing in-app terminals and log streamers. The handlers authenticate the session through validateRequest() but never consult the role or permission model enforced on every tRPC procedure. Any authenticated organization member can open an interactive shell into any container on the host, including the dokploy container that mounts the Docker socket. From that shell, an attacker obtains root on the host, escaping the application and crossing every tenant boundary. The issue is tracked as [CWE-269: Improper Privilege Management] and fixed in version 0.29.13.
Critical Impact
Any authenticated Dokploy member can spawn a root shell in the dokploy container, abuse the mounted Docker socket, and take over the underlying host across all tenants.
Affected Products
- Dokploy self-hosted PaaS, all versions prior to 0.29.13
- Dokploy WebSocket handlers for container terminal, container logs, and container stats
- Multi-tenant Dokploy deployments where organization members share a host
Discovery Timeline
- 2026-08-10 - CVE CVE-2026-72863 published to NVD
- 2026-08-10 - Last updated in NVD database
- Fixed release - Dokploy v0.29.13 published with authorization patch (see GitHub Release v0.29.13 and GHSA-7r6p-v9gw-pwc8)
Technical Details for CVE-2026-72863
Vulnerability Analysis
Dokploy exposes real-time features (container terminal, container logs, container stats) over WebSocket endpoints. Every tRPC procedure in the application enforces role-based checks such as docker: ["read"] and validates that a target serverId is reachable by the caller. The WebSocket handlers bypass that layer entirely. They call validateRequest() to confirm the user has a valid session and an active organization, then attach to any container the caller names. There is no check that the user is an owner, admin, or a member explicitly granted canAccessToDocker.
Because the dokploy container itself mounts the host Docker socket, an authenticated attacker can request a shell inside that container and issue Docker commands against the host daemon. From there the attacker runs a privileged container mounting /, escaping the application sandbox and taking root on the host. Every tenant hosted on that node is exposed.
Root Cause
The WebSocket authorization layer performed authentication without authorization. validateRequest() established identity and activeOrganizationId, but the handler never called into the permission service used by tRPC. The fix introduces canAccessDockerOverWss(), which builds a tRPC-equivalent context and calls hasPermission(ctx, { docker: ["read"] }). For remote servers, it also checks the server is in the caller's getAccessibleServerIds set.
Attack Vector
An attacker with any valid Dokploy member account connects to the container terminal WebSocket endpoint. The attacker supplies the container ID of the dokploy container or any other tenant's container. The server upgrades the connection and spawns an interactive shell without checking permissions. The attacker then runs Docker CLI commands against the mounted socket to launch a privileged container that binds the host filesystem.
// Patch: apps/dokploy/server/wss/authorize.ts
// Introduces authorization for docker/terminal WebSocket handlers.
import { getAccessibleServerIds } from "@dokploy/server";
import {
findMemberByUserId,
hasPermission,
} from "@dokploy/server/services/permission";
type WssUser = { id: string } | null | undefined;
type WssSession = { activeOrganizationId?: string | null } | null | undefined;
const buildCtx = (user: { id: string }, activeOrganizationId: string) => ({
user: { id: user.id },
session: { activeOrganizationId },
});
// Requires the docker permission (owner/admin, or a member explicitly granted
// canAccessToDocker) and, for a remote server, that the server is accessible
// to the caller. Previously these handlers only checked session + organization,
// so any member could reach a root shell / logs of any container.
export const canAccessDockerOverWss = async (
user: WssUser,
session: WssSession,
serverId?: string | null,
): Promise<boolean> => {
if (!user || !session?.activeOrganizationId) return false;
const ctx = buildCtx(user, session.activeOrganizationId);
if (!(await hasPermission(ctx, { docker: ["read"] }))) return false;
// ...
Source: GitHub Commit 68f5afa
Detection Methods for CVE-2026-72863
Indicators of Compromise
- WebSocket upgrade requests to Dokploy terminal, logs, or stats endpoints originating from low-privilege member accounts targeting containers outside their project scope.
- Unexpected docker run invocations from inside the dokploy container, especially with -v /:/host or --privileged flags.
- New privileged containers on the host with host root filesystem bind mounts that were not created by CI or platform automation.
- Interactive node-pty shells (/bin/sh, /bin/bash) spawned by the Dokploy Node.js process against containers unrelated to the initiating user's tenant.
Detection Strategies
- Inspect Dokploy access logs for WebSocket sessions where the authenticated user's role is member and the targeted containerId maps to another organization or to the dokploy container itself.
- Correlate Docker daemon audit logs with Dokploy application logs to identify container creations that lack a matching authorized tRPC action.
- Alert on any process tree where node (Dokploy) is the parent of a shell whose child issues docker commands with privileged flags.
Monitoring Recommendations
- Enable Docker daemon logging with --log-level=info and forward events to a central log store for retention and query.
- Monitor host-level auditd or eBPF sensors for mounts of the Docker socket (/var/run/docker.sock) into newly created containers.
- Track the deployed Dokploy version across all hosts and alert on any instance still running below 0.29.13.
How to Mitigate CVE-2026-72863
Immediate Actions Required
- Upgrade Dokploy to 0.29.13 or later on every host, following the GitHub Release v0.29.13 instructions.
- Rotate any secrets, API tokens, and SSH keys reachable from the dokploy container, assuming compromise until logs are reviewed.
- Review the organization membership list and revoke accounts that should not have Dokploy access.
- Audit Docker daemon and Dokploy logs for suspicious terminal WebSocket sessions and unexpected privileged containers created since deployment.
Patch Information
The fix landed in commit 68f5afa and is included in Dokploy v0.29.13. The patch adds canAccessDockerOverWss() in apps/dokploy/server/wss/authorize.ts and calls it from the container terminal, container logs, and container stats WebSocket handlers. The check enforces docker: ["read"] permission and validates access to remote serverId values. Refer to GHSA-7r6p-v9gw-pwc8 for the official advisory.
Workarounds
- If immediate patching is not possible, restrict Dokploy membership to trusted operators only and remove all non-admin member accounts.
- Place Dokploy behind a network policy or reverse proxy that limits WebSocket endpoints to a small set of source IPs.
- Run Dokploy on dedicated single-tenant hosts to remove the cross-tenant blast radius until the upgrade is applied.
# Upgrade Dokploy to the patched release
curl -sSL https://dokploy.com/install.sh | sh
# Or, for Docker-based deployments, pull the fixed image and redeploy
docker pull dokploy/dokploy:0.29.13
docker service update --image dokploy/dokploy:0.29.13 dokploy
# Verify the running version
docker exec -it dokploy sh -c 'cat package.json | grep version'
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

