Skip to main content
Glama

mcp-text-editor

by tumf
MIT License
159
  • Apple
  • Linux
test_path_validation.py5.55 kB
"""Tests for path validation security utilities.""" import os import tempfile from pathlib import Path import pytest from mcp_text_editor.utils import normalize_and_validate_path class TestPathValidation: """Test path validation security features.""" def test_valid_relative_path(self): """Test that valid relative paths are accepted.""" with tempfile.TemporaryDirectory() as tmpdir: result = normalize_and_validate_path("test.txt", tmpdir) expected = str(Path(tmpdir).resolve() / "test.txt") assert result == expected def test_valid_nested_relative_path(self): """Test that valid nested relative paths are accepted.""" with tempfile.TemporaryDirectory() as tmpdir: result = normalize_and_validate_path("subdir/test.txt", tmpdir) expected = str(Path(tmpdir).resolve() / "subdir" / "test.txt") assert result == expected def test_reject_absolute_path(self): """Test that absolute paths are rejected.""" with tempfile.TemporaryDirectory() as tmpdir: with pytest.raises(ValueError, match="Absolute paths are not allowed"): normalize_and_validate_path("/etc/passwd", tmpdir) def test_reject_directory_traversal_dotdot(self): """Test that directory traversal with .. is rejected.""" with tempfile.TemporaryDirectory() as tmpdir: with pytest.raises(ValueError, match="Directory traversal patterns"): normalize_and_validate_path("../etc/passwd", tmpdir) with pytest.raises(ValueError, match="Directory traversal patterns"): normalize_and_validate_path("subdir/../../../etc/passwd", tmpdir) def test_reject_home_directory_expansion(self): """Test that home directory expansion ~ is rejected.""" with tempfile.TemporaryDirectory() as tmpdir: with pytest.raises(ValueError, match="Directory traversal patterns"): normalize_and_validate_path("~/test.txt", tmpdir) def test_reject_empty_path(self): """Test that empty paths are rejected.""" with tempfile.TemporaryDirectory() as tmpdir: with pytest.raises(ValueError, match="File path cannot be empty"): normalize_and_validate_path("", tmpdir) def test_reject_path_outside_base_directory(self): """Test that paths resolving outside base directory are rejected.""" with tempfile.TemporaryDirectory() as tmpdir: # Create a symlink that points outside the base directory outside_file = "/tmp/outside.txt" try: with open(outside_file, "w") as f: f.write("test") symlink_path = Path(tmpdir) / "symlink.txt" symlink_path.symlink_to(outside_file) with pytest.raises( ValueError, match="Path resolves outside of allowed base directory" ): normalize_and_validate_path("symlink.txt", tmpdir) finally: # Clean up if os.path.exists(outside_file): os.unlink(outside_file) def test_path_with_current_directory_refs(self): """Test paths with . references are normalized correctly.""" with tempfile.TemporaryDirectory() as tmpdir: result = normalize_and_validate_path("./test.txt", tmpdir) expected = str(Path(tmpdir).resolve() / "test.txt") assert result == expected def test_windows_style_paths_rejected(self): """Test that Windows-style paths with backslashes are handled.""" with tempfile.TemporaryDirectory() as tmpdir: # This should work as it's just a filename with backslashes result = normalize_and_validate_path("test\\file.txt", tmpdir) expected = str(Path(tmpdir).resolve() / "test\\file.txt") assert result == expected def test_path_injection_attempts(self): """Test various path injection attempts are blocked.""" with tempfile.TemporaryDirectory() as tmpdir: malicious_paths = [ "../../../etc/passwd", "..\\..\\..\\windows\\system32\\config\\sam", "..%2F..%2F..%2Fetc%2Fpasswd", # URL encoded "....//....//....//etc/passwd", # Double dots "..\\..\\..", "~/../../../etc/passwd", "/..", "/./../../etc/passwd", ] for path in malicious_paths: with pytest.raises(ValueError): normalize_and_validate_path(path, tmpdir) def test_null_byte_injection(self): """Test that null byte injection is handled.""" with tempfile.TemporaryDirectory() as tmpdir: with pytest.raises((ValueError, OSError)): normalize_and_validate_path("test.txt\x00../../etc/passwd", tmpdir) def test_base_directory_normalization(self): """Test that base directory is properly normalized.""" with tempfile.TemporaryDirectory() as tmpdir: # Use a base directory with .. in it weird_base = os.path.join(tmpdir, "subdir", "..", "actual") os.makedirs(os.path.join(tmpdir, "actual"), exist_ok=True) result = normalize_and_validate_path("test.txt", weird_base) expected = str(Path(tmpdir).resolve() / "actual" / "test.txt") assert result == expected

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/tumf/mcp-text-editor'

If you have feedback or need assistance with the MCP directory API, please join our Discord server