# Command Blocklist in DesktopCommanderMCP: Purpose, Configuration, and Security Best Practices

> Learn how to configure the command blocklist in DesktopCommanderMCP to enhance security by preventing risky command execution. Secure your system with these best practices.

- Repository: [Eduard Ruzga/DesktopCommanderMCP](https://github.com/wonderwhy-er/DesktopCommanderMCP)
- Tags: best-practices
- Published: 2026-08-03

---

**The command blocklist in DesktopCommanderMCP prevents execution of high-risk shell commands like `sudo`, `iptables`, and `rm` by validating parsed command tokens against a configurable array of blocked names before execution.**

DesktopCommanderMCP enables remote execution of shell commands on a host device, which creates inherent security risks. The **command blocklist** serves as a critical safeguard against accidental damage or malicious exploitation. This article explains how the blocklist works, where it's configured, and how to customize it for your security requirements.

## How the Command Blocklist Works

The blocklist enforcement happens in two stages within the command manager: parsing and validation.

### Command Parsing with `extractCommands()`

When a raw command string arrives, `commandManager.extractCommands()` in [`dist/command-manager.js`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/dist/command-manager.js) performs several normalizations:

- Resolves absolute paths to command names
- Expands command substitutions (`$()` and backticks)
- Strips variable tokens (`$VAR`)

This parsing ensures that attempts to bypass the blocklist using obfuscation techniques are caught before validation.

### Validation with `validateCommand()`

The parsed command tokens are then checked against the blocklist:

```javascript
// dist/command-manager.js (simplified structure)
export const commandManager = {
  extractCommands(raw) {
    // Normalizes paths, expands substitutions, strips variables
    return parsedTokens; // e.g., ['sudo', 'ls']
  },

  async validateCommand(raw) {
    const cmds = this.extractCommands(raw);
    const blocklist = this.config.commandBlocklist;
    for (const cmd of cmds) {
      if (blocklist.includes(cmd)) {
        throw new Error(`Command "${cmd}" is blocked`);
      }
    }
    return true;
  }
};

```

The test suite in [`test/test-blocklist-bypass.js`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/test/test-blocklist-bypass.js) verifies that these normalizations correctly prevent bypass attempts through absolute paths, command substitutions, and backticks.

## Configuring the Command Blocklist

The blocklist is defined as a JSON array in the DesktopCommanderMCP configuration file.

### Configuration File Location

- **Global config**: [`config.json`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/config.json) or `.desktopcommanderrc` in the application directory
- **Project-specific config**: `.desktopcommanderrc` in the project root (takes precedence)

### Blocklist Format

```json
{
  "commandBlocklist": ["sudo", "iptables", "rm", "dd", "chmod"]
}

```

### Modifying the Blocklist

- **Add a command**: Append the command name to the array
- **Remove a command**: Delete the entry from the array
- **Project override**: Define `commandBlocklist` in a local config file; this merges with or overrides the global list

### Runtime Behavior

- The blocklist loads when the command manager initializes
- Configuration changes require a restart of DesktopCommanderMCP or a configuration reload via the UI
- Only **exact command names** are blocked; the parsing stage ensures aliases and wrappers invoking blocked commands are still caught

## Testing Blocklist Enforcement

The repository includes comprehensive tests demonstrating expected behavior:

```javascript
// test/test-blocked-commands.js
import { commandManager } from '../dist/command-manager.js';

// Blocked commands are rejected
await assert.rejects(
  commandManager.validateCommand('sudo reboot now'),
  /blocked/
);

// Allowed commands pass through
await assert.doesNotReject(
  commandManager.validateCommand('ls -la')
);

```

The [`test/test-blocklist-bypass.js`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/test/test-blocklist-bypass.js) file specifically validates that normalization prevents evasion attempts:

- `/usr/bin/sudo reboot` → parsed as `sudo` → blocked
- `$(which sudo) reboot` → parsed as `sudo` → blocked
- `` `which sudo` reboot `` → parsed as `sudo` → blocked

## Common Commands to Block

| Command Category | Examples | Risk |
|------------------|----------|------|
| Privilege escalation | `sudo`, `su` | Unauthorized root access |
| Network manipulation | `iptables`, `ufw` | Firewall bypass or lockout |
| Data destruction | `rm`, `dd`, `mkfs` | Irreversible data loss |
| Permission changes | `chmod`, `chown` | Security policy violations |
| System control | `shutdown`, `reboot` | Denial of service |

## Summary

- The **command blocklist** in DesktopCommanderMCP prevents execution of dangerous shell commands by validating normalized tokens against a configurable array
- **Configuration** occurs in [`config.json`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/config.json) or `.desktopcommanderrc` via the `commandBlocklist` array
- **Parsing normalization** in `extractCommands()` prevents bypass attempts through paths, substitutions, or variables
- **Changes require restart** to take effect, and project-specific configs can override global settings
- **Test suites** in [`test/test-blocked-commands.js`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/test/test-blocked-commands.js) and [`test/test-blocklist-bypass.js`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/test/test-blocklist-bypass.js) verify enforcement behavior

## Frequently Asked Questions

### Where is the command blocklist defined in DesktopCommanderMCP?

The blocklist is defined in the `commandBlocklist` array within the configuration file—typically [`config.json`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/config.json) or `.desktopcommanderrc` at the application or project root. The array contains command names as strings that should be prohibited from execution.

### How does DesktopCommanderMCP prevent blocklist bypass attempts?

The `commandManager.extractCommands()` function normalizes command strings before validation by resolving absolute paths, expanding command substitutions (`$()` and backticks), and stripping variable references. This ensures that `/usr/bin/sudo`, `$(which sudo)`, and similar obfuscations are all identified as the blocked command `sudo`.

### Can I set different blocklists for different projects?

Yes. Create a `.desktopcommanderrc` file in a project directory with a `commandBlocklist` entry. DesktopCommanderMCP merges project-specific configurations with global settings, giving precedence to local definitions when conflicts occur.

### Do blocklist changes take effect immediately?

No. The blocklist loads during command manager initialization. After modifying the configuration file, you must restart DesktopCommanderMCP or trigger a configuration reload through the UI for changes to become active.