Security Implications of Using Docker Isolation in Desktop Commander MCP
Desktop Commander MCP uses Docker containers to isolate MCP tool execution, but runs containers as root with unrestricted capabilities and mounts persistent host volumes, creating potential breakout risks if the container is compromised.
Desktop Commander MCP by wonderwhy-er implements containerization through Docker to sandbox command execution. While the approach uses minimal Alpine-based images and transient containers, the security implications of using Docker isolation in Desktop Commander MCP require careful consideration due to privileged user contexts and expansive volume mounting strategies.
Docker Isolation Architecture
The project containerizes the Node.js application using instructions defined in the Dockerfile. The installer script install-docker.sh orchestrates volume creation and runtime configuration through Bash functions including setup_persistent_volumes and build_docker_args.
Base Image Selection
The Dockerfile specifies FROM node:lts-alpine, providing a minimal Alpine Linux environment with Long-Term Support Node.js. This reduces the attack surface compared to full distributions, though the image still contains the Node runtime and requires regular updates via docker pull mcp/desktop-commander:latest to incorporate upstream security patches.
Container User Context
By default, the container executes CMD ["node","dist/index.js"] as the root user. The absence of a USER instruction in the Dockerfile means the process maintains full control over the container's filesystem, escalating the impact of any container breakout vulnerability.
Critical Security Vulnerabilities
Several configuration choices in the current implementation introduce elevated risk profiles that operators must understand before deployment.
Root User Execution Risks
The build_docker_args function in install-docker.sh constructs runtime parameters but does not include --user flags or UID/GID mappings. If a container escape occurs via kernel exploitation, the attacker gains root access to the host system. Adding a non-root user instruction such as USER node to the Dockerfile would mitigate this privilege escalation path.
Persistent Volume Exposure
The setup_persistent_volumes function creates four named volumes—dc-system, dc-home, dc-workspace, and dc-packages—mounted read-write into the container. While these persist data across container lifetimes, they also provide a persistence mechanism for attackers. Compromise of the container grants access to cached SSH keys stored in dc-home or package credentials in dc-packages.
Host Directory Mounting
The ask_for_folders function prompts users to specify host directories, which build_docker_args then bind-mounts under /home inside the container. These mounts inherit host filesystem permissions, allowing the containerized process to read and write any mounted files. Users should limit selections to specific project directories rather than exposing entire home folders containing .ssh keys or environment files.
Missing Security Hardening Flags
The generated Docker commands lack capability dropping and privilege restrictions. Specifically, the scripts omit --cap-drop ALL and --security-opt no-new-privileges:true flags. Without these restrictions, the container retains default Linux capabilities including SYS_ADMIN, significantly increasing the blast radius of potential container escapes.
Supply Chain and Runtime Execution
The Dockerfile mitigates some supply chain risks by running npm install --ignore-scripts, which prevents malicious npm post-install hooks from executing during the build. However, this also disables legitimate build steps that some dependencies might require. The install-docker.sh script itself executes with user privileges and runs Docker commands based on interactive input, requiring absolute trust in the installer integrity.
Mitigation Strategies
Operators can harden the deployment through specific modifications to the configuration files:
- Run as non-root: Modify
install-docker.shto append--user $(id -u):$(id -g)to thedocker runarguments, or update theDockerfileto includeUSER nodebefore theCMDinstruction. - Restrict capabilities: Edit
build_docker_argsto include--cap-drop ALLand--security-opt no-new-privileges:truein the Docker runtime flags. - Limit mounted folders: When
ask_for_foldersexecutes, select only the minimum directories required for the specific session, avoiding sensitive configuration directories. - Secure persistent data: Treat
dc-homeanddc-systemvolumes as sensitive storage requiring filesystem permissions restrictions and potential encryption at the host level. - Maintain updates: Regularly execute
docker pull mcp/desktop-commander:latestto receive Alpine Linux and Node.js security patches.
Summary
- Desktop Commander MCP uses
node:lts-alpinewith four persistent volumes (dc-system,dc-home,dc-workspace,dc-packages) created bysetup_persistent_volumes. - Containers execute as root with full Linux capabilities, creating significant breakout risks if exploited.
- Host directory mounts via
ask_for_foldersexpose filesystems to container processes with host-level permissions. - Hardening requires modifying
install-docker.shto add--cap-drop ALL,--security-opt no-new-privileges:true, and non-root user constraints.
Frequently Asked Questions
Does Desktop Commander MCP run containers as root?
Yes. The Dockerfile does not specify a USER instruction, causing the Node.js process to run as root inside the container. This configuration could lead to host compromise if combined with a container escape vulnerability.
What directories can the Docker container access?
By default, the container accesses four named volumes created by setup_persistent_volumes. Additionally, the ask_for_folders function in install-docker.sh mounts user-specified host directories under /home, potentially exposing SSH keys, Git configurations, and project secrets if the user selects those paths.
How can I secure the persistent volumes created by the installer?
Treat volumes dc-home and dc-system as sensitive storage containing authentication data. Limit which host directories you mount through ask_for_folders, regularly clean unused volumes with docker volume prune, and consider encrypting the volume backing stores at the host filesystem level to protect against offline attacks.
Are there network exposure risks with Desktop Commander MCP?
No inbound exposure exists. The build_docker_args function does not publish ports (-p), keeping the container unreachable from external networks. However, outbound connections from the container operate through the host network stack, inheriting the host's network policies and potential monitoring gaps.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →