#!/usr/bin/env python3 """Unit tests for path handling and security.""" import sys import tempfile from pathlib import Path from urllib.parse import unquote sys.path.insert(0, str(Path(__file__).parent.parent)) def test_path_traversal_blocked(): """Test that path traversal is blocked in archive routes.""" archive_dir = Path(tempfile.mkdtemp()) def validate_archive_path(archive_path: str): decoded = unquote(archive_path) try: archive_file = (archive_dir / decoded).resolve() if not str(archive_file).startswith(str(archive_dir)): return None return archive_file except (ValueError, OSError): return None for bad_path in [ "../../../etc/passwd", "..%2F..%2F..%2Fetc%2Fpasswd", "../secret.txt", "websites/../../etc/passwd", ]: result = validate_archive_path(bad_path) assert result is None, f"Traversal should be blocked: {bad_path}" print(f" PASS: blocked '{bad_path}'") valid = validate_archive_path("websites/Test/html/2024-01-01/article.html") assert valid is not None assert str(valid).startswith(str(archive_dir)) print(f" PASS: allowed valid path") def test_path_traversal_file_access(): """Test that path traversal cannot read files outside archive dir.""" archive_dir = Path(tempfile.mkdtemp()) secret_file = archive_dir.parent / "secret.txt" secret_file.write_text("top secret") def validate_archive_path(archive_path: str): decoded = unquote(archive_path) try: archive_file = (archive_dir / decoded).resolve() if not str(archive_file).startswith(str(archive_dir)): return None return archive_file except (ValueError, OSError): return None blocked = validate_archive_path(f"../secret.txt") assert blocked is None print(f" PASS: file access traversal blocked") secret_file.unlink() def test_url_encoding(): """Test URL encoding/decoding in archive paths.""" archive_file_path = "websites/404 Media/html/2024-01-15/article_001.html" encoded = archive_file_path.replace(" ", "%20") decoded = unquote(encoded) assert decoded == archive_file_path print(f" PASS: encoding round-trip") if __name__ == "__main__": test_path_traversal_blocked() test_path_traversal_file_access() test_url_encoding() print("\nAll path handling tests passed!")