How Desktop Commander’s Command Blocklist Security Prevents Dangerous Shell Operations

Desktop Commander protects users from accidental or malicious shell commands by maintaining a personal safety blocklist that is enforced at runtime through deep command parsing capable of detecting dangerous operations hidden inside command substitution and backticks.

Desktop Commander MCP implements robust command blocklist security to safeguard against catastrophic shell operations. The wonderwhy-er/DesktopCommanderMCP repository contains a multi-layered defense system that parses complex shell syntax, extracts nested commands, and validates them against a user-configurable blocklist before execution occurs.

Configuring the Blocklist in src/config-field-definitions.ts

The foundation of the security system resides in the user-editable configuration. The blockedCommands field is defined in src/config-field-definitions.ts (lines 11-15), where it is declared as an array of strings that users can populate with prohibited operations. This allows individuals to specify high-risk commands they never want executed, such as rm -rf, format, or shutdown, creating a personalized safety barrier against data loss.

Extracting Commands with CommandManager.extractCommands

When processing a prompt containing complex shell syntax, Desktop Commander invokes CommandManager.extractCommands to perform deep parsing. This method walks the input string character-by-character while respecting quotes and escape sequences, ensuring that every sub-command is identified for subsequent validation.

Detecting $() Command Substitution

The parser specifically addresses blocklist bypass attempts using command substitution. In src/command-manager.ts (lines 58-78), the extraction logic identifies commands nested within $() constructs. This ensures that dangerous operations cannot slip through disguised as variable expansions, as the parser extracts the inner command and subjects it to the same security checks as top-level commands.

Handling Backtick Substitution

Similarly, backtick command substitution is handled in src/command-manager.ts (lines 82-100). The code identifies commands wrapped in backticks, preventing attackers or accidental prompts from executing blocked commands through this alternative syntax. By extracting these hidden commands, the system ensures they are included in the validation sweep.

Runtime Validation with CommandManager.validateCommand

Once extraction is complete, CommandManager.validateCommand (lines 29-51 in src/command-manager.ts) performs the actual security enforcement. The method retrieves the current blocklist from the configuration (lines 31-34) and iterates through every extracted command (lines 44-49). If any command matches an entry in the blockedCommands array, the method returns false and the shell operation is aborted before reaching the execution stage.

Fail-Closed Safety Mechanism

The implementation follows security best practices by failing closed. If an error occurs while reading the configuration or during the validation process, CommandManager.validateCommand returns false (lines 54-60). This ensures that a malfunction—such as a corrupted config file or parsing exception—cannot result in the unintentional execution of a blocked command. The system defaults to denial rather than permission when uncertainty arises.

Practical Configuration Examples

// Adding dangerous commands to the blocklist
await configManager.updateConfig({
  blockedCommands: ['rm -rf', 'shutdown', 'format']
});
// Attempting to bypass with command substitution - BLOCKED
const userPrompt = "echo start && $(rm -rf /) && echo done";
const ok = await commandManager.validateCommand(userPrompt);
console.log(ok); // → false
// Attempting to bypass with backticks - BLOCKED
const prompt = "ls && `rm -rf /tmp/*` && echo finished";
const ok = await commandManager.validateCommand(prompt);
console.log(ok); // → false
// Safe command passes validation
const safePrompt = "git status && echo \"All good\"";
const ok = await commandManager.validateCommand(safePrompt);
console.log(ok); // → true

Verification and Testing

The repository includes comprehensive verification in test/test-blocklist-bypass.js, which tests the blocklist bypass mitigation strategies to ensure that command substitution and backtick tricks cannot circumvent the security controls. Detailed security considerations are documented in SECURITY.md, and the feature is highlighted in the README.md under the "Security Hardening" section.

Summary

  • Desktop Commander maintains a user-editable blockedCommands list defined in src/config-field-definitions.ts (lines 11-15)
  • The CommandManager.extractCommands method parses shell syntax including $() (lines 58-78) and backtick substitution (lines 82-100) to find hidden commands
  • CommandManager.validateCommand checks extracted commands against the blocklist (lines 29-51) and rejects matches before execution
  • Fail-closed behavior ensures that errors in validation result in command rejection (lines 54-60) rather than unintended execution
  • Bypass protection is tested in test/test-blocklist-bypass.js to prevent evasion through shell trickery

Frequently Asked Questions

How does the command blocklist security in Desktop Commander handle complex shell commands?

Desktop Commander uses the CommandManager.extractCommands method to parse shell strings character-by-character while respecting quotes and escape sequences. According to the source code in src/command-manager.ts, it specifically extracts commands hidden inside $() (lines 58-78) and backtick substitutions (lines 82-100), then validates each component against the blockedCommands list before allowing execution.

Can users customize which commands are blocked?

Yes, users can customize the blocklist through the blockedCommands configuration field. As defined in src/config-field-definitions.ts (lines 11-15), this user-editable array accepts any command strings the user wishes to prohibit, such as rm -rf, format, or shutdown, providing a personal safety net against dangerous operations.

What happens if the validation system encounters an error?

The system implements fail-closed behavior. If CommandManager.validateCommand encounters an error while reading the configuration or during the validation process, it returns false (as seen in lines 54-60 of src/command-manager.ts). This ensures that a malfunction cannot result in the unintentional execution of a blocked command.

Where can I find tests for the blocklist bypass protection?

The repository includes a dedicated test suite in test/test-blocklist-bypass.js that verifies the blocklist bypass mitigation. These tests ensure that commands hidden inside command substitution and backticks are properly detected and blocked, confirming that the security mechanisms cannot be circumvented through shell trickery.

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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →