Security Limitations of DesktopCommanderMCP: allowedDirectories and Command Blocking Explained
DesktopCommanderMCP's security features default to permissive states that grant full filesystem and shell access unless explicitly configured, creating significant security risks if left unchanged.
DesktopCommanderMCP provides two primary security mechanisms—allowedDirectories for filesystem sandboxing and blockedCommands for shell execution restrictions—but both ship with dangerous default configurations that assume trust rather than enforce least privilege. Understanding these security limitations is critical for anyone deploying this Model Context Protocol (MCP) server in production environments, as the out-of-the-box settings in src/config-manager.ts effectively disable all protective barriers.
Default Configuration: The Empty Array Vulnerability
The most critical security limitation lies in how DesktopCommanderMCP interprets empty configuration arrays. According to the source code in src/config-manager.ts, both security features initialize to empty arrays ([]), which the server interprets as permission granted rather than permission denied.
allowedDirectoriesdefaults to[](lines 12-14), meaning the server can read or write to any path on the filesystem without restriction.blockedCommandsdefaults to[](lines 10-13), meaning all shell commands are permitted unless explicitly added to the blocklist.
This design choice contradicts security best practices of default-deny policies. The UI in src/ui/config-editor/src/app.ts displays warnings when these arrays are empty—such as "All folders allowed (no restriction)"—but the server does not enforce any mandatory configuration, leaving inexperienced users vulnerable to accidental data destruction or unauthorized access.
Filesystem Validation Logic and Bypass Prevention
When allowedDirectories is populated, the Filesystem helper class in src/tools/filesystem.ts (lines 172-209) implements path validation through getAllowedDirs(). The enforcement mechanism includes several protective layers:
Path Resolution Strategy:
- Canonical path normalization to eliminate directory traversal sequences (
../). - Symlink resolution to prevent bypass attacks where a symlink inside an allowed directory points to a restricted location outside the whitelist.
- Sub-directory inheritance allowing access to child folders of whitelisted paths (e.g.,
/home/user/docsis permitted when/home/useris listed). - Root-drive shortcuts handling for Windows systems (e.g.,
C:\).
If validation fails, the server throws a structured error: Path not allowed: <path>. Must be within one of these directories: …. However, the limitation remains that this robust validation only activates when administrators explicitly populate the allowedDirectories array defined in src/config-field-definitions.ts (lines 16-20).
Command Blocking Limitations and Execution Gaps
The command blocking feature in src/command-manager.ts (lines 233-247) provides a secondary safety net, but suffers from similar opt-in weaknesses. The CommandManager extracts the base command from user input—parsing rm -rf /tmp down to rm—and checks it against config.blockedCommands.
Key Limitations:
- Blacklist approach: Only explicitly listed commands are blocked; novel dangerous commands or renamed binaries bypass the filter.
- No argument inspection: The blocker checks only the command name, not dangerous flags (e.g., blocking
rmpreventsrm -rf /but also prevents benignrm file.txt, while a renamed scriptdelete.shcontainingrm -rf /would execute unhindered). - Default permissiveness: With an empty default array, the server spawns subprocesses without any validation of the executable being invoked.
When a blocked command is detected, the server returns: { type: "text", text: "Error: Command not allowed: <command>" }.
Configuring Secure Restrictions
To mitigate these security limitations, administrators must explicitly define boundaries in config.json or through the configuration UI.
Recommended Secure Configuration:
{
"allowedDirectories": ["/home/user/projects", "/var/log/app"],
"blockedCommands": ["rm", "shutdown", "reboot", "mkfs", "dd"]
}
Dangerous Configuration (Default State):
{
"allowedDirectories": [],
"blockedCommands": []
}
The following TypeScript examples demonstrate the runtime enforcement:
// Attempting to access files outside the whitelist
await filesystem.readFile('/etc/passwd');
// Error: Path not allowed: /etc/passwd. Must be within one of these directories: /home/user/projects, /var/log/app
// Attempting to execute a blocked command
await commandManager.run('rm -rf /tmp/*');
// { type: "text", text: "Error: Command not allowed: rm" }
Summary
- Default permissiveness: Both
allowedDirectoriesandblockedCommandsdefault to empty arrays insrc/config-manager.ts, granting unrestricted filesystem and shell access until configured otherwise. - Path validation: The
Filesystemclass insrc/tools/filesystem.tsprovides robust whitelist enforcement including symlink resolution, but only when directories are explicitly specified. - Command filtering:
CommandManagerinsrc/command-manager.tsblocks only base command names from a user-maintained list, without inspecting arguments or preventing execution of unknown binaries. - Explicit opt-in required: Security protections are entirely optional; the server comments in
src/server.ts(lines 314-346) document this behavior, but do not mandate configuration. - UI warnings: The configuration editor in
src/ui/config-editor/src/app.tswarns users about unrestricted access, but does not enforce security policies.
Frequently Asked Questions
What happens if I leave allowedDirectories empty in DesktopCommanderMCP?
If allowedDirectories remains an empty array []—the default value set in src/config-manager.ts—the server interprets this as permission to access the entire filesystem. The validation logic in src/tools/filesystem.ts skips all path restrictions, allowing read and write operations anywhere on the host system, including sensitive system files and directories outside the user's home folder.
Can DesktopCommanderMCP prevent command injection attacks?
DesktopCommanderMCP's blockedCommands feature provides limited protection against known dangerous commands by checking the base executable name against a user-defined blacklist in src/command-manager.ts. However, it cannot prevent command injection attacks involving renamed binaries, shell scripts containing malicious commands, or dangerous arguments to permitted commands, as the validation only inspects the command name and does not parse or sanitize command-line arguments.
How does DesktopCommanderMCP handle symbolic links outside allowed directories?
The Filesystem validation logic in src/tools/filesystem.ts resolves symbolic links to their canonical targets before checking against the allowedDirectories whitelist. This prevents symlink bypass attacks where a link inside an allowed directory points to a restricted location outside the approved path tree, ensuring that indirect path access cannot circumvent the directory restrictions.
Where are the security settings defined and stored?
Security settings are defined in src/config-field-definitions.ts (lines 11-20), which specifies the schema for both blockedCommands and allowedDirectories. The actual values are persisted and loaded by src/config-manager.ts, with runtime enforcement implemented in src/tools/filesystem.ts for path validation and src/command-manager.ts for command blocking. Server documentation regarding these security features appears in the comments of src/server.ts (lines 312-346).
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 →