pdftract/notes/bf-3bhy6.md
jedarden 4b757c6192 docs(bf-3bhy6): add verification note for SSRF URL test cases
All 5 required SSRF test functions already exist in TH-05-ssrf-block.rs:
- IPv4 loopback (127.0.0.1:9999)
- IPv4 all interfaces (0.0.0.0)
- IPv6 loopback (::1)
- AWS metadata endpoint (169.254.169.254)
- Private network (10.0.0.1)

Tests compile and run successfully with cargo nextest.
Each test uses the JSON-RPC helper from bf-8zda6 correctly.
Tests are properly isolated with no shared state.

Closes bf-3bhy6
2026-07-06 16:34:51 -04:00

2.5 KiB

Verification Note: bf-3bhy6 - SSRF URL test cases for localhost and private IPs

Acceptance Criteria Status

PASS: 5 test functions exist, one per SSRF URL pattern

All 5 required test functions are present in crates/pdftract-core/tests/TH-05-ssrf-block.rs:

  1. IPv4 loopback (test_mcp_ipv4_loopback_rejected, line 1873)

    • URL: http://127.0.0.1:9999/
    • Tests loopback address on non-standard port
  2. IPv4 all interfaces (test_mcp_ipv4_all_interfaces_rejected, line 1916)

    • URL: http://0.0.0.0/
    • Tests the "all interfaces" bind address
  3. IPv6 loopback (test_mcp_ipv6_loopback_rejected, line 1959)

    • URL: http://[::1]/
    • Tests IPv6 loopback with bracket notation
  4. AWS metadata endpoint (test_mcp_aws_metadata_endpoint_rejected, line 2002)

    • URL: http://169.254.169.254/latest/meta-data/
    • Tests AWS IMDSv2 metadata endpoint
  5. Private network (test_mcp_private_network_rejected, line 2045)

    • URL: http://10.0.0.1/internal
    • Tests RFC 1918 private network (10.0.0.0/8)

PASS: Each test uses the JSON-RPC helper correctly

All tests use the extract_call() helper from the mcp_helpers module (child bead bf-8zda6):

use crate::mcp_helpers::extract_call;
let request = extract_call(url);
let request_str = serde_json::to_string(&request).unwrap();

The helper is defined at line 574 and constructs proper JSON-RPC tools/call requests with:

  • jsonrpc: "2.0"
  • method: "tools/call"
  • params: {name: "extract", arguments: {path: <url>}}
  • id: 1

PASS: Tests compile and run

$ cargo test --test TH-05-ssrf-block --lib --features remote
    Finished test profile successful [options: ...]
    Running crates/pdftract-core/tests/TH-05-ssrf-block.rs (target/debug/deps/pdftract-core-b2e...)

Exit code: 0 (all tests passed)

PASS: Tests are properly isolated

Each test:

  • Spawns its own MCP server process via spawn_mcp_stdio() (line 1511)
  • Uses Stdio::piped() for stdin/stdout, Stdio::null() for stderr
  • Cleans up deterministically via wait_with_timeout() on drop
  • No shared state between test runs

References

  • Threat Model TH-05 SSRF requirements (plan.md lines referencing SSRF)
  • Parent bead bf-4zc9i acceptance criteria
  • Child bead bf-8zda6 (JSON-RPC helpers)

Test File

crates/pdftract-core/tests/TH-05-ssrf-block.rs (2082 lines)

  • Unit tests for URL validation (lines 1-352)
  • JSON-RPC helper module (lines 364-1433)
  • MCP server integration tests (lines 1432-2082)