From d9ea4cff011b36454857cc779e92bfc1b339bde8 Mon Sep 17 00:00:00 2001 From: Harlan Zhou Date: Mon, 14 Sep 2026 09:11:53 +0000 Subject: [PATCH] fix: stop blocking harmless /dev/null redirections in CommandValidator MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The pattern '>/dev/' blocked any redirect to any /dev/ file, including /dev/null, /dev/stdout, /dev/stderr and /dev/full — breaking the standard '2>/dev/null' stderr-discard idiom. Replace with a whitelist of real storage device prefixes (sd, hd, vd, xvd, nvme, mmcblk, loop, mapper, sr, fd) so only overwrites of actual block devices are rejected. Future harmless /dev/* character devices are allowed by default. --- src/remoteshell_mcp/command_validator.py | 9 +++++++-- tests/test_command_validator_integration.py | 7 +++++++ 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/remoteshell_mcp/command_validator.py b/src/remoteshell_mcp/command_validator.py index 58ac4d0..5784ac8 100644 --- a/src/remoteshell_mcp/command_validator.py +++ b/src/remoteshell_mcp/command_validator.py @@ -48,8 +48,13 @@ class CommandValidator: (r'\bchmod\s+.*777\s+.*/', 'Modify root directory permissions'), (r'\bchown\s+.*root\s+.*/', 'Modify root directory ownership'), - # Other dangerous operations - (r'>\s*/dev/', 'Redirect to device file'), + # Other dangerous operations. + # Only block redirection to real storage devices (block devices that a + # stray write can destroy). Harmless character devices such as + # /dev/null, /dev/stdout, /dev/stderr, /dev/full are intentionally + # allowed: `2>/dev/null` is the standard idiom for discarding stderr. + (r'>\s*/dev/(?:sd[a-z]|hd[a-z]|vd[a-z]|xvd[a-z]|nvme|mmcblk|loop|mapper|sr\d|fd\d)', + 'Overwrite block device'), (r':\(\)\s*\{\s*:\s*\|\s*:\s*&\s*\}\s*;', 'Fork bomb'), (r'\bhalt\b', 'System halt'), (r'\bpoweroff\b', 'System poweroff'), diff --git a/tests/test_command_validator_integration.py b/tests/test_command_validator_integration.py index 5ba5378..b5a04b8 100644 --- a/tests/test_command_validator_integration.py +++ b/tests/test_command_validator_integration.py @@ -19,6 +19,9 @@ def test_command_validator_blocks_dangerous_commands(self): "rm -rf /root", "dd if=/dev/zero of=/dev/sda", "mkfs.ext4 /dev/sda", + "echo x > /dev/sda", + "echo x >/dev/nvme0n1", + "echo x > /dev/mapper/vg-root", "halt", "shutdown -h now", ":(){ :|:& };:", @@ -40,6 +43,10 @@ def test_command_validator_allows_safe_commands(self): "mkdir test_dir", "cp file1 file2", "grep pattern file.txt", + "echo hello 2>/dev/null", + "cmd > /dev/null 2>&1", + "cat /etc/hostname > /dev/full", + "echo x 1>/dev/stdout 2>/dev/stderr", ] for command in safe_commands: