"""Unit tests for input sanitization and secure configuration handling.""" import json import tempfile import os import shutil from pathlib import Path from typing import Dict, Any import pytest from src.security.input_sanitization import ( sanitize_sql_input, sanitize_html_input, sanitize_command_input, sanitize_file_path, sanitize_config_value, validate_config_schema, sanitize_search_query, sanitize_environment_variable, InputSanitizationError, ConfigValidationError, ) class TestSQLInputSanitization: """Test SQL input sanitization functions.""" def test_sanitize_sql_input_removes_sql_injection(self): """Test that SQL injection attempts are sanitized.""" malicious_inputs = [ "'; DROP TABLE users; --", "' OR '1'='1", "'; INSERT INTO users VALUES ('hacker', 'password'); --", "admin'--", "'; UPDATE users SET password='hacked'; --", ] for malicious_input in malicious_inputs: sanitized = sanitize_sql_input(malicious_input) assert "DROP" not in sanitized assert "INSERT" not in sanitized assert "UPDATE" not in sanitized assert "DELETE" not in sanitized assert ";" not in sanitized assert "--" not in sanitized assert "/*" not in sanitized assert "*/" not in sanitized def test_sanitize_sql_input_preserves_safe_input(self): """Test that safe input is preserved.""" safe_inputs = [ "normal text", "user123", "search query", "file_name.txt", "path/to/file", ] for safe_input in safe_inputs: sanitized = sanitize_sql_input(safe_input) assert sanitized == safe_input def test_sanitize_sql_input_handles_edge_cases(self): """Test edge cases for SQL input sanitization.""" # Empty input assert sanitize_sql_input("") == "" assert sanitize_sql_input(None) == "" # Whitespace only assert sanitize_sql_input(" ") == " " # Very long input long_input = "a" * 1000 sanitized = sanitize_sql_input(long_input) assert len(sanitized) <= 1000 def test_sanitize_sql_input_raises_error_for_critical_attacks(self): """Test that critical SQL injection attempts raise errors.""" critical_attacks = [ "'; DROP DATABASE; --", "'; SHUTDOWN; --", "'; EXEC xp_cmdshell; --", ] for attack in critical_attacks: with pytest.raises(InputSanitizationError): sanitize_sql_input(attack) class TestHTMLInputSanitization: """Test HTML input sanitization functions.""" def test_sanitize_html_input_removes_xss_attempts(self): """Test that XSS attempts are sanitized.""" xss_attempts = [ "", "", "javascript:alert('xss')", "", "", ] for xss_attempt in xss_attempts: sanitized = sanitize_html_input(xss_attempt) assert "Bold text", "Italic text", "Link", ] for html in safe_html: sanitized = sanitize_html_input(html) # Should preserve the original tag if "

" in html: assert "

" in sanitized elif "" in html: assert "" in sanitized elif "" in html: assert "" in sanitized elif "" in html: assert "" in sanitized def test_sanitize_html_input_handles_edge_cases(self): """Test edge cases for HTML input sanitization.""" # Empty input assert sanitize_html_input("") == "" assert sanitize_html_input(None) == "" # Plain text assert sanitize_html_input("plain text") == "plain text" # Mixed content mixed = "Normal text more text" sanitized = sanitize_html_input(mixed) assert "" # Apply all sanitization functions sql_safe = sanitize_sql_input(malicious_input) html_safe = sanitize_html_input(sql_safe) command_safe = sanitize_command_input(html_safe) # Should be safe after all sanitization assert "DROP" not in command_safe assert "