fix: block bind mounts to sensitive host paths for non-owner/admin members - #5254
Open
Siumauricio wants to merge 1 commit into
Open
fix: block bind mounts to sensitive host paths for non-owner/admin members#5254Siumauricio wants to merge 1 commit into
Siumauricio wants to merge 1 commit into
Conversation
…mbers The Mounts feature (application/compose/database services) let any member with volume:create access set an arbitrary bind mount hostPath, with zero validation. Since generateBindMounts wires that path straight into the Swarm service spec, a non-privileged member could mount /var/run/docker.sock, /etc/dokploy, or other host-critical paths and escalate to root on the Dokploy control host - same impact as bringing your own docker-compose.yml with a docker.sock mount, but reachable through the plain Mounts UI on any service type. Add isDangerousBindMountPath() with a fixed blocklist of host-critical paths (docker.sock, /etc/dokploy, /root, /boot, /proc, /sys, docker's data dir) and isPrivilegedOrgRole(); mount.create/update now reject a bind mount targeting one of those paths unless the caller is the org's owner or admin. Single-user self-hosted installs are unaffected - the sole user is always the owner.
Comment on lines
+46
to
+48
| return DANGEROUS_HOST_PATH_PREFIXES.some( | ||
| (prefix) => normalized === prefix || normalized.startsWith(`${prefix}/`), | ||
| ); |
Contributor
There was a problem hiding this comment.
Parent paths bypass socket block
When a non-owner/admin member binds /run or /var/run, this descendant-only comparison classifies the path as safe even though it contains the blocked docker.sock; generateBindMounts then forwards that directory directly to Docker, exposing daemon control inside the workload and enabling host takeover.
How this was verified: The accepted parent path is passed unchanged as the Docker bind mount Source, making its docker.sock child available under the mount target.
Knowledge Base Used:
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The Mounts feature (bind mounts on applications, compose, and database services) let any member with
volume:createaccess set an arbitrary bind mounthostPath, with zero validation.generateBindMountswires that path straight into the Swarm service spec, so a non-privileged member could mount/var/run/docker.sock,/etc/dokploy, or other host-critical paths and escalate to root on the Dokploy control host — same impact as bringing your owndocker-compose.ymlwith a docker.sock mount, but reachable through the plain Mounts UI on any service type, no Compose needed.isDangerousBindMountPath()(fixed blocklist: docker.sock,/etc/dokploy,/root,/boot,/proc,/sys, docker's data dir) andisPrivilegedOrgRole().mount.create/mount.updatenow reject a bind mount targeting one of those paths unless the caller is the organization's owner or admin.Verified live: as the org owner, mounting both a safe path and
/var/run/docker.sockstill succeeds (no regression).Greptile Summary
The PR adds role-sensitive validation intended to prevent non-owner/admin members from binding security-critical host paths into managed workloads.
Confidence Score: 3/5
The PR is not safe to merge until parent-directory bind mounts that expose protected paths such as the Docker socket are blocked.
A non-privileged member can bind
/runor/var/run, which passes the new predicate and is forwarded directly to Docker, exposingdocker.sockinside the workload.Files Needing Attention: packages/server/src/services/mount.ts
Security Review
The restriction remains bypassable by binding a parent directory such as
/runor/var/run; the resulting workload can still access the enclosed Docker socket and obtain host-level control.Reviews (1): Last reviewed commit: "fix: block bind mounts to sensitive host..." | Re-trigger Greptile
Context used: