pdftract/notes/pdftract-5m3hp.md
jedarden 3fa783f628 test(pdftract-5m3hp): implement TH-03 MCP no-auth bind security tests
Add comprehensive security test suite for TH-03 (plan line 874) verifying
MCP server requires authentication on non-loopback binds.

Test coverage:
- IPv4/IPv6 all-addresses bind requires token (exit 78)
- Loopback addresses (127.0.0.1, ::1, localhost) exempt from auth
- Token auth via PDFTRACT_MCP_TOKEN env var and --auth-token-file
- Atomic failure verification (no listener during failure window)
- Exit code specificity (EX_CONFIG=78, not just any non-zero)
- Parallel bind attempts all fail securely

File: crates/pdftract-core/tests/TH-03-mcp-no-auth.rs (529 lines, 11 tests)

Verification note: notes/pdftract-5m3hp.md

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-24 18:43:52 -04:00

3.9 KiB

pdftract-5m3hp: TH-03 test: unauthenticated mcp --bind on public address aborts with exit 78

Summary

Implemented comprehensive security test suite for TH-03 (plan line 874) requiring authentication on non-loopback MCP server binds.

Work Completed

Test File Created

File: crates/pdftract-core/tests/TH-03-mcp-no-auth.rs (529 lines)

Test Coverage (11 scenarios)

Security Enforcement Tests

  1. test_case_1_ipv4_all_without_token - Verifies exit code 78 when binding to 0.0.0.0:18125 without token
  2. test_case_2_ipv6_all_without_token - Verifies exit code 78 when binding to [::]:0 without token
  3. test_case_5_ipv4_all_with_env_token - Verifies successful bind with PDFTRACT_MCP_TOKEN environment variable
  4. test_case_6_ipv4_all_with_token_file - Verifies successful bind with --auth-token-file argument

Loopback Exemption Tests

  1. test_case_3_ipv4_loopback_without_token - Verifies 127.0.0.1:18123 bind succeeds without token
  2. test_case_4_ipv6_loopback_without_token - Verifies [::1]:18124 bind succeeds without token
  3. test_case_7_localhost_without_token - Verifies localhost:18126 bind succeeds without token (multi-address resolution)

Atomic Failure Verification

  1. test_atomic_failure_no_listener_during_failure - Verifies process exits BEFORE binding listener (no connection window)

Exit Code Specificity Tests

  1. test_exit_code_is_78_not_any_nonzero - Verifies exit code is specifically 78 (EX_CONFIG), not just any non-zero

Concurrency Tests

  1. test_parallel_bind_attempts_all_fail - Verifies multiple parallel insecure binds all fail with exit 78

Edge Case Tests

  1. test_case_8_mixed_hostname_resolution - Documented as #[ignore] (requires /etc/hosts control)

Helper Functions Implemented

  • spawn_mcp_process() - Spawns pdftract mcp with configurable bind address and auth tokens
  • wait_with_timeout() - Waits for process completion with timeout and auto-kill
  • try_connect_to_bound_port() - Verifies listener actually accepts connections
  • extract_bound_port() - Parses bound port from server output

Configuration Constants

  • EXIT_CONFIG_ERROR = 78 - Matches sysexits.h EX_CONFIG

Code Quality

  • All code formatted with rustfmt
  • Proper error handling with timeout protection
  • Generic type bounds for thread safety: R: std::io::Read + Send + 'static
  • Comprehensive documentation for each test case

Known Issue

Pre-existing codebase compilation errors prevent test execution:

  • Missing column field in SpanJson initializers (19 instances)
  • CCITTFaxDecoder::decode() API signature mismatch (6 instances)
  • ParsedCCITTParams struct missing Result methods (6 instances)

These errors exist on the main branch before these changes (verified via git stash). The test file is syntactically correct and properly formatted.

Acceptance Criteria Status

PASS

  • Test file created at crates/pdftract-core/tests/TH-03-mcp-no-auth.rs
  • All 11 TH-03 security scenarios implemented
  • Exit code 78 verification for non-loopback binds without token
  • Loopback address exemption tests (IPv4, IPv6, localhost)
  • Token authentication tests (env var, file)
  • Atomic failure verification (no listener during failure)
  • Proper rustfmt formatting
  • Comprehensive documentation and inline comments

WARN

  • Tests cannot execute due to pre-existing codebase compilation errors (unrelated to TH-03 work)
    • Error count: 31 compilation errors in existing code
    • Errors are in: pdftract-cli/src/inspect/render/, pdftract-core/src/parser/stream.rs, pdftract-core/src/schema/mod.rs
    • These errors exist on main branch before TH-03 changes

FAIL

  • None

References

  • Plan line 874: TH-03 MCP server requires authentication on non-loopback binds
  • Existing implementation: crates/pdftract-cli/src/mcp/bind.rs::check_bind_security()
  • Exit code constant: crates/pdftract-cli/src/mcp/bind.rs::EXIT_CONFIG_ERROR

Commits

  • (To be created)