"""Security tests for input validation.""" import pytest @pytest.mark.security class TestInputValidation: """Test input validation edge cases and security.""" def test_url_validation_rejects_javascript_protocol(self): """Test that javascript: URLs are rejected.""" from urllib.parse import urlparse # Test URL parsing rejects javascript: protocol url = "javascript:alert(1)" parsed = urlparse(url) # javascript: is not http or https assert parsed.scheme not in ("http", "https") def test_url_validation_rejects_data_protocol(self): """Test that data: URLs are rejected.""" from urllib.parse import urlparse url = "data:text/html," parsed = urlparse(url) # data: is not http or https assert parsed.scheme not in ("http", "https") def test_url_validation_rejects_file_protocol(self): """Test that file: URLs are rejected.""" from urllib.parse import urlparse url = "file:///etc/passwd" parsed = urlparse(url) # file: is not http or https assert parsed.scheme not in ("http", "https") def test_url_validation_handles_very_long_urls(self): """Test that URL validation handles very long URLs.""" from gondulf.utils.validation import validate_redirect_uri long_url = "https://example.com/" + "a" * 10000 client_id = "https://example.com" # Should handle without crashing (may reject) try: is_valid = validate_redirect_uri(long_url, client_id) # If it doesn't crash, that's acceptable except Exception as e: # Should not be a crash, should be a validation error assert "validation" in str(e).lower() or "invalid" in str(e).lower() def test_email_validation_rejects_injection(self): """Test that email validation rejects injection attempts.""" import re # Email validation pattern email_pattern = r"^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}$" malicious_emails = [ "user@example.com\nBcc: attacker@evil.com", "user@example.com\r\nSubject: Injected", "user@example.com", ] for email in malicious_emails: is_valid = re.match(email_pattern, email) assert not is_valid, f"Email injection allowed: {email}" def test_null_byte_injection_rejected(self): """Test that null byte injection is rejected in URLs.""" from gondulf.utils.validation import validate_redirect_uri malicious_url = "https://example.com\x00.attacker.com" client_id = "https://example.com" # Should reject null byte in URL is_valid = validate_redirect_uri(malicious_url, client_id) assert not is_valid, "Null byte injection allowed" def test_domain_special_characters_handled(self): """Test that special characters in domains are handled safely.""" from gondulf.utils.validation import validate_redirect_uri client_id = "https://example.com" # Test various special characters special_char_domains = [ "https://example.com/../attacker.com", "https://example.com/..%2Fattacker.com", "https://example.com/%00attacker.com", ] for url in special_char_domains: is_valid = validate_redirect_uri(url, client_id) # Should either reject or handle safely