pdftract/notes/pdftract-6696g.md
jedarden 8dff70e404 docs(pdftract-6696g): add verification note for --root path-traversal protection
The --root DIR flag was already fully implemented in the codebase.
All 25 tests pass (12 unit + 13 integration tests).

Acceptance criteria verified:
- Path traversal rejected with -32602
- Absolute paths rejected when --root is set
- HTTPS URLs bypass the check
- Symlink escapes detected via canonicalize
- Startup validation for root directory

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-05-23 02:29:26 -04:00

3 KiB

pdftract-6696g: Path-traversal protection via --root DIR

Summary

The --root CLI flag for MCP server path-traversal protection was already implemented in the codebase. This verification note confirms the implementation meets all acceptance criteria.

Implementation Location

  • CLI flag: crates/pdftract-cli/src/main.rs lines 112-119
  • Path resolution: crates/pdftract-cli/src/mcp/root.rs lines 39-76 (resolve_path)
  • Root validation: crates/pdftract-cli/src/mcp/root.rs lines 78-102 (canonicalize_root)
  • Tool integration: crates/pdftract-cli/src/mcp/tools/registry.rs line 203 (open_pdf calls resolve_path)

Acceptance Criteria Verification

Criterion Status Evidence
Path traversal ../../etc/passwd → -32602 PASS Test: test_acceptance_criteria_path_traversal_rejected
Valid path ./subdir/file.pdf → success PASS Test: test_acceptance_criteria_valid_path_within_root
Absolute path /etc/passwd → -32602 PASS Test: test_acceptance_criteria_absolute_path_rejected
HTTPS URL bypasses check PASS Test: test_acceptance_criteria_https_url_bypasses_check
No --root → trust-the-caller mode PASS Test: test_acceptance_criteria_no_root_trust_the_caller
Symlink escape → -32602 PASS Test: test_acceptance_criteria_symlink_escape_rejected
Nonexistent --root → startup error PASS Test: test_acceptance_criteria_nonexistent_root_startup_error
--root is file → startup error PASS Test: test_acceptance_criteria_file_not_directory_startup_error
Plan critical test PASS Test: test_plan_critical_test_path_traversal_with_root

Test Results

All 25 tests pass:

  • Unit tests (root.rs): 12 tests passed
  • Integration tests (root-path-protection.rs): 13 tests passed
$ cargo test --test root-path-protection
test result: ok. 13 passed; 0 failed; 0 ignored

$ cargo test --package pdftract-cli --lib mcp::root
test result: ok. 12 passed; 0 failed; 0 ignored

Key Security Features

  1. Canonicalization: std::fs::canonicalize follows symlinks, ensuring the resolved path is checked
  2. Absolute path rejection: Explicit check for / prefix when --root is set
  3. HTTPS bypass: URLs starting with http:// or https:// skip path resolution
  4. Structured errors: All failures return JSON-RPC error code -32602 with descriptive messages

CLI Help Output

--root <DIR>
    Root directory for local filesystem access (enforces path-traversal protection)

    When set, all local-path tool arguments are resolved relative to DIR and any
    path that escapes DIR is rejected with JSON-RPC error code -32602. HTTPS URLs
    are not affected by this flag. Without --root, the server runs in
    trust-the-caller mode (no path-check applied).

No Code Changes Required

The implementation was already complete. This bead was a verification task rather than an implementation task.