Skip to main content
Glama

Command-Line MCP Server

by andresthor
test_security.py14.9 kB
"""Tests for the security module.""" from cmd_line_mcp.security import validate_command, parse_command def test_validate_command_success_cases(): """Test successful validation of commands.""" # Setup test data read_commands = ["ls", "cat", "grep", "find", "head", "tail"] write_commands = ["mkdir", "touch", "rm", "cp", "mv"] system_commands = ["ps", "top", "who", "netstat"] blocked_commands = ["sudo", "su", "eval", "exec"] dangerous_patterns = [ "rm -rf /", "/etc/passwd", "/etc/shadow", "> /dev/sda", ] # Test valid read command result = validate_command( "ls -la", read_commands, write_commands, system_commands, blocked_commands, dangerous_patterns, ) assert result["is_valid"] is True assert result["command_type"] == "read" assert result["error"] is None # Test valid write command result = validate_command( "mkdir /tmp/test", read_commands, write_commands, system_commands, blocked_commands, dangerous_patterns, ) assert result["is_valid"] is True assert result["command_type"] == "write" assert result["error"] is None # Test valid system command result = validate_command( "ps aux", read_commands, write_commands, system_commands, blocked_commands, dangerous_patterns, ) assert result["is_valid"] is True assert result["command_type"] == "system" assert result["error"] is None def test_validate_command_blocked_commands(): """Test validation of blocked commands.""" # Setup test data read_commands = ["ls", "cat"] write_commands = ["mkdir", "touch"] system_commands = ["ps", "top"] blocked_commands = ["sudo", "su", "eval", "exec"] dangerous_patterns = [] # Test a blocked command without any dangerous patterns # so we can isolate the blocked command validation result = validate_command( "sudo ls", read_commands, write_commands, system_commands, blocked_commands, dangerous_patterns, ) assert result["is_valid"] is False assert result["command_type"] is None assert result["error"] is not None assert ( "blocked" in result["error"].lower() or "sudo" in result["error"].lower() ) # Test a command with the blocked command as an argument result = validate_command( "echo 'sudo is not allowed'", read_commands, write_commands, system_commands, blocked_commands, dangerous_patterns, ) assert result["is_valid"] is False # Should still catch this assert result["command_type"] is None assert result["error"] is not None def test_validate_command_dangerous_patterns(): """Test validation of dangerous patterns.""" # Setup test data read_commands = ["ls", "cat"] write_commands = ["rm"] system_commands = ["ps"] blocked_commands = ["sudo"] dangerous_patterns = [ r"rm\s+-rf\s+/", r"/etc/passwd", r"/etc/shadow", r">\s+/dev/sda", r"\$\(", # Command substitution - use raw string with proper escaping ] # Test a dangerous pattern result = validate_command( "rm -rf /", read_commands, write_commands, system_commands, blocked_commands, dangerous_patterns, ) assert result["is_valid"] is False assert result["command_type"] is None assert result["error"] is not None assert "dangerous pattern" in result["error"].lower() # Test command with dangerous pattern embedded result = validate_command( "cat /etc/passwd", read_commands, write_commands, system_commands, blocked_commands, dangerous_patterns, ) assert result["is_valid"] is False assert result["command_type"] is None assert result["error"] is not None assert "dangerous pattern" in result["error"].lower() # Test command with command substitution using properly escaped pattern result = validate_command( "echo $(ls -la)", read_commands, write_commands, system_commands, blocked_commands, dangerous_patterns, ) assert result["is_valid"] is False assert result["command_type"] is None assert result["error"] is not None def test_validate_command_unsupported_commands(): """Test validation of unsupported commands.""" # Setup test data read_commands = ["ls", "cat"] write_commands = ["mkdir", "touch"] system_commands = ["ps", "top"] blocked_commands = ["sudo"] dangerous_patterns = ["rm -rf /"] # Test a command that's not in any list result = validate_command( "unsupported_command", read_commands, write_commands, system_commands, blocked_commands, dangerous_patterns, ) assert result["is_valid"] is False assert result["command_type"] is None assert result["error"] is not None assert "unsupported" in result["error"].lower() def test_validate_command_with_pipes(): """Test validation of commands with pipes.""" # Setup test data read_commands = ["ls", "cat", "grep", "sort", "head"] write_commands = ["mkdir", "touch"] system_commands = ["ps", "top"] blocked_commands = ["sudo"] # Use empty list for dangerous patterns to avoid pipe issues dangerous_patterns = [] # Test a valid piped command with all supported commands result = validate_command( "ls -la | grep 'file' | sort -r | head -5", read_commands, write_commands, system_commands, blocked_commands, dangerous_patterns, ) assert result["is_valid"] is True assert result["command_type"] == "read" assert result["error"] is None # Test a piped command with an unsupported command result = validate_command( "ls -la | unsupported_command", read_commands, write_commands, system_commands, blocked_commands, dangerous_patterns, ) assert result["is_valid"] is False assert result["command_type"] is None assert result["error"] is not None # Test a piped command with a blocked command result = validate_command( "ls -la | sudo cat /etc/passwd", read_commands, write_commands, system_commands, blocked_commands, dangerous_patterns, ) assert result["is_valid"] is False assert result["command_type"] is None assert result["error"] is not None def test_validate_command_with_semicolons(): """Test validation of commands with semicolons.""" # Setup test data read_commands = ["ls", "cat", "pwd"] write_commands = ["mkdir", "touch"] system_commands = ["ps"] blocked_commands = ["sudo"] dangerous_patterns = ["rm -rf /"] # Test a valid sequence of commands result = validate_command( "mkdir temp; ls -la; pwd", read_commands, write_commands, system_commands, blocked_commands, dangerous_patterns, ) assert result["is_valid"] is True # The command type should be the most privileged one (write in this case) assert result["command_type"] == "write" assert result["error"] is None # Test a sequence with an unsupported command result = validate_command( "mkdir temp; unsupported_command", read_commands, write_commands, system_commands, blocked_commands, dangerous_patterns, ) assert result["is_valid"] is False assert result["command_type"] is None assert result["error"] is not None def test_validate_command_with_special_characters(): """Test validation of commands with special shell characters.""" # Setup test data read_commands = ["ls", "cat", "echo"] write_commands = ["mkdir"] system_commands = ["ps"] blocked_commands = ["sudo"] # Commands with environment variables should be valid # Using no dangerous patterns for this test dangerous_patterns = [] # Test a command with environment variable substitution result = validate_command( "echo $HOME", read_commands, write_commands, system_commands, blocked_commands, dangerous_patterns, ) # This should be valid because $HOME is a legitimate env var assert result["is_valid"] is True assert result["command_type"] == "read" # Now use a specific dangerous pattern to test brace expansion dangerous_patterns = [r"\$\{.*:\d+:\d+\}"] # Match ${var:x:y} pattern # Test a command with dangerous brace expansion result = validate_command( "echo ${PATH:0:10}", read_commands, write_commands, system_commands, blocked_commands, dangerous_patterns, ) assert result["is_valid"] is False assert result["command_type"] is None assert result["error"] is not None def test_parse_command(): """Test parsing command strings.""" # Test normal command cmd, args = parse_command("ls -la") assert cmd == "ls" assert args == ["-la"] # Test command with multiple arguments cmd, args = parse_command("grep -r pattern ./dir") assert cmd == "grep" assert args == ["-r", "pattern", "./dir"] # Test command with quoted arguments cmd, args = parse_command('grep "complex pattern" file.txt') assert cmd == "grep" assert args == ["complex pattern", "file.txt"] # Test empty command cmd, args = parse_command("") assert cmd == "" assert args == [] # Test command starting with dash (for pipe continuation) cmd, args = parse_command("-v pattern") assert cmd == "" assert args == ["-v pattern"] def test_validate_command_with_separator_control(): """Test command validation with separator control.""" # Setup test data read_commands = ["ls", "cat", "grep"] write_commands = ["mkdir", "touch"] system_commands = ["ps"] blocked_commands = ["sudo"] dangerous_patterns = [] # Test with separators allowed (default) result = validate_command( "ls -la | grep pattern", read_commands, write_commands, system_commands, blocked_commands, dangerous_patterns, allow_command_separators=True, ) assert result["is_valid"] is True assert result["command_type"] == "read" # Test with separators disallowed result = validate_command( "ls -la | grep pattern", read_commands, write_commands, system_commands, blocked_commands, dangerous_patterns, allow_command_separators=False, ) assert result["is_valid"] is False assert result["command_type"] is None assert "separators" in result["error"].lower() # Test semicolon with separators disallowed result = validate_command( "mkdir test; ls -la", read_commands, write_commands, system_commands, blocked_commands, dangerous_patterns, allow_command_separators=False, ) assert result["is_valid"] is False assert result["command_type"] is None assert "separators" in result["error"].lower() # Test ampersand with separators disallowed result = validate_command( "ps aux &", read_commands, write_commands, system_commands, blocked_commands, dangerous_patterns, allow_command_separators=False, ) assert result["is_valid"] is False assert result["command_type"] is None assert "separators" in result["error"].lower() def test_command_type_elevation(): """Test that command type is properly elevated to the most privileged type.""" # Setup test data read_commands = ["ls", "cat", "grep"] write_commands = ["mkdir", "touch"] system_commands = ["ps"] blocked_commands = ["sudo"] dangerous_patterns = [] # Test with all read commands result = validate_command( "ls -la | grep pattern | cat file.txt", read_commands, write_commands, system_commands, blocked_commands, dangerous_patterns, ) assert result["is_valid"] is True assert result["command_type"] == "read" # Test with mixed read and write commands result = validate_command( "ls -la; mkdir test", read_commands, write_commands, system_commands, blocked_commands, dangerous_patterns, ) assert result["is_valid"] is True assert result["command_type"] == "write" # Test with mixed read, write, and system commands result = validate_command( "ls -la; mkdir test; ps aux", read_commands, write_commands, system_commands, blocked_commands, dangerous_patterns, ) assert result["is_valid"] is True assert result["command_type"] == "system" def test_custom_command_list(): """Test validation with custom command lists to ensure they're respected.""" # Custom command lists including awk and jq read_commands = ["ls", "cat", "grep", "awk", "jq"] write_commands = ["mkdir", "touch"] system_commands = ["ps"] blocked_commands = ["sudo"] dangerous_patterns = [] # Test awk in a simple command result = validate_command( "awk '{print $1}' file.txt", read_commands, write_commands, system_commands, blocked_commands, dangerous_patterns, ) assert result["is_valid"] is True assert result["command_type"] == "read" # Test awk in a pipeline with other commands result = validate_command( "cat file.txt | awk '{print $1}' | grep pattern", read_commands, write_commands, system_commands, blocked_commands, dangerous_patterns, ) assert result["is_valid"] is True assert result["command_type"] == "read" # Test jq in a pipeline result = validate_command( "cat data.json | jq '.name'", read_commands, write_commands, system_commands, blocked_commands, dangerous_patterns, ) assert result["is_valid"] is True assert result["command_type"] == "read" # Verify command not in custom list is rejected result = validate_command( "sed 's/old/new/g' file.txt", # sed not in our custom list read_commands, write_commands, system_commands, blocked_commands, dangerous_patterns, ) assert result["is_valid"] is False assert "not recognized" in result["error"] assert "sed" in result["error"]

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/andresthor/cmd-line-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server