Configuring Custom Command Blocklists with Bypass Protection in DesktopCommanderMCP

DesktopCommanderMCP provides a regex-based command blocklist with built-in bypass protection that normalizes input, detects evasion techniques like sub-shells and chained commands, and rejects unauthorized execution before reaching the host shell.

DesktopCommanderMCP implements a robust security layer through its configurable command blocklist system. This Multi-Channel Processor (MCP) feature allows administrators to define regex patterns that block dangerous shell commands while including sophisticated bypass protection to prevent circumvention through aliases, escaped characters, or indirect invocations. The blocklist engine operates as a pre-execution gatekeeper, ensuring that even complex obfuscation attempts are caught before any command reaches the host operating system.

How the Blocklist Engine Works

The MCP command execution pipeline follows a strict validation sequence defined in the core execution module. When a command is submitted, the processor does not immediately pass it to the shell. Instead, it runs the input through the blocklist engine implemented in src/commandExecutor.ts (or equivalent core logic).

Input Normalization

Before pattern matching begins, the engine normalizes the command string. This process involves trimming whitespace, expanding environment variables, and resolving any shell aliases to their underlying commands. Normalization ensures that blocklist patterns match against the canonical form of the command, preventing simple evasion through formatting tricks.

Regex Pattern Matching

The normalized command is then tested against the commandBlocklist array defined in config.json. Each entry is a standard JavaScript regular expression. The engine evaluates patterns sequentially, and if any match is found, the command is immediately blocked with a BLOCKED_COMMAND error code.

// config.json
{
  "commandBlocklist": [
    "rm\\s+-rf\\s+.*",
    "shutdown|reboot",
    "^.*\\b(cat|more)\\b.*$",
    "^curl\\s+https?://"
  ]
}

Bypass Protection Layer

After the initial blocklist check, the bypass-protection layer analyzes the command for common evasion techniques. This includes detecting escaped characters (using \ to hide spaces), command chaining (via && or ||), and sub-shell invocations (such as sh -c or $(...)). If any such pattern is detected, the command is rejected even if it would otherwise slip past the raw blocklist.

Configuring Your Custom Blocklist

To customize command restrictions, edit the config.json file located in the repository root. The commandBlocklist array accepts standard JavaScript RegExp strings.

Default Blocklist Examples

The default configuration includes protections against destructive operations:

{
  "commandBlocklist": [
    "rm\\s+-rf\\s+.*",               // Prevents recursive deletes
    "shutdown|reboot",               // Disallows system shutdown/reboot
    "^.*\\b(cat|more)\\b.*$",        // Blocks misuse of cat/more for large files
    "^curl\\s+https?://.*"           // Restricts curl to external URLs
  ]
}

Adding Custom Patterns

When adding new entries, use valid JavaScript regex syntax. Patterns are case-sensitive by default and match against the entire normalized command string. For example, to block specific script execution:

{
  "commandBlocklist": [
    "^python\\s+.*\\.py$",           // Blocks Python script execution
    "\\bwget\\b.*\\-O\\s+/etc"       // Prevents wget from writing to /etc
  ]
}

Applying Configuration Changes

After modifying config.json, apply changes without restarting the service by invoking the built-in reload command:

await mcp.sendCommand('reload');   // Re-loads config and blocklist in memory

Bypass Protection Mechanisms

The test/test-blocklist-bypass.js file validates that the bypass protection correctly identifies and rejects obfuscated commands. The protection layer specifically targets:

  • Sub-shell execution: Commands wrapped in sh -c "..." or bash -c "..." are analyzed to ensure the inner command is not blocked.
  • Command chaining: Inputs containing &&, ||, or ; are rejected if any component matches a blocklist pattern.
  • Escape sequences: Attempts to hide keywords using backslashes or encoded characters are detected during normalization.
// Example from test-blocklist-bypass.js validation suite
await expect(
  mcp.sendCommand('sh -c "rm -rf /tmp/important"')
).rejects.toMatchObject({ code: 'BLOCKED_COMMAND' });

await expect(
  mcp.sendCommand('echo "test" && rm -rf /tmp/data')
).rejects.toMatchObject({ code: 'BLOCKED_COMMAND' });

Testing Blocklist Enforcement

The repository includes comprehensive test suites to verify blocklist functionality. The test/test-blocked-commands.js file tests direct blocklist matches, while test/test-blocklist-bypass.js specifically validates bypass protection.

Running Validation Tests

When implementing custom patterns, validate them against the existing test framework:

// test-blocklist-bypass.js validates that obfuscated commands are caught
const blockedCommands = [
  'sh -c "rm -rf /"',           // Sub-shell evasion
  'echo hello && shutdown now', // Command chaining
  '\\u0072m -rf /tmp'           // Unicode escape attempts
];

for (const cmd of blockedCommands) {
  await expect(mcp.sendCommand(cmd))
    .rejects.toMatchObject({ code: 'BLOCKED_COMMAND' });
}

Summary

  • DesktopCommanderMCP uses a regex-based blocklist defined in config.json to prevent dangerous command execution.
  • The engine normalizes input (resolving aliases, expanding variables) before testing against blocklist patterns.
  • Bypass protection detects evasion techniques including sub-shells, command chaining, and escape characters.
  • Changes take effect immediately after calling the reload command or upon service restart.
  • The test suites in test/test-blocklist-bypass.js and test/test-blocked-commands.js ensure both direct blocks and bypass attempts are rejected.

Frequently Asked Questions

How does DesktopCommanderMCP prevent command bypass techniques?

The bypass protection layer analyzes normalized commands for evasion patterns such as sub-shell invocations (sh -c), command chaining (&&, ||), and escaped characters. Even if a command obfuscates a blocked keyword through these methods, the additional validation layer detects the pattern and rejects the execution with a BLOCKED_COMMAND error.

Where is the blocklist configuration stored?

The blocklist configuration resides in the config.json file at the repository root. This JSON file contains the commandBlocklist array, which holds JavaScript regular expression strings defining prohibited command patterns.

What regex format should I use for blocklist patterns?

DesktopCommanderMCP uses standard JavaScript RegExp syntax. Patterns should be formatted as strings in the JSON array, with double-escaped backslashes (e.g., "rm\\s+-rf" instead of /rm\s+-rf/). The engine tests these patterns against the normalized command string.

How do I apply changes without restarting the service?

After editing config.json, invoke the built-in reload functionality by sending the reload command to the MCP instance: await mcp.sendCommand('reload'). This reloads the configuration and blocklist patterns into memory without requiring a full service restart.

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 →