"""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