Skip to content

test(cache): pin the remove_cached containment guard against a symlink escape - #135

Merged
MichaelTaylor3d merged 1 commit into
mainfrom
test/1622-containment-guard-coverage
Aug 2, 2026
Merged

test(cache): pin the remove_cached containment guard against a symlink escape#135
MichaelTaylor3d merged 1 commit into
mainfrom
test/1622-containment-guard-coverage

Conversation

@MichaelTaylor3d

Copy link
Copy Markdown
Contributor

What changed

Closes #1622.

(a) — the containment guard was untested (fixed). remove_cached_rejects_path_traversal fed a non-hex key ("../../etc"), which the 64-hex validator (CapsuleKey::parse) refuses before any path is built — so the canonicalize + starts_with(cache) containment guard in capsule_store.rs (cache_remove_cached) was never exercised. If that guard were deleted, the test still passed.

A valid 64-hex key can't contain .//, so it can never escape <cache>/modules on its own — the guard is defense-in-depth against a compromised cache layout. The new test exercises it directly:

  • remove_cached_containment_guard_refuses_a_symlink_escape (#[cfg(unix)]): plants a symlink at <cache>/modules/<store> → a separate out-of-cache tempdir holding <root>.module, then asserts a well-formed cache_remove_cached is refused ("outside the cache") and the outside file survives.
  • Mutation-verified: with the guard block deleted the test FAILS (the outside file is unlinked); with it restored it passes. The test pins the guard.
  • Renamed the existing test → remove_cached_rejects_a_non_canonical_key_at_the_validator so each test names the gate it actually pins.

(b) — already satisfied, no change. #1622's second concern (the availability-batch non-canonical-key test being vacuous) is already resolved in current code: availability_batch_rejects_a_non_canonical_key_without_touching_the_filesystem now plants a real out-of-cache secret.module and drives .. / ../secret traversals that collapse onto it, so available == false is non-vacuous — it would answer true without the guard. Documented in the commit body; nothing to change.

Verification

  • New + renamed tests green; mutation check confirms the new test fails without the guard.
  • cargo fmt --all -- --check clean · cargo clippy -p dig-node-core --all-targets --all-features -D warnings clean.

Version

test: → patch bump [workspace.package].version 0.72.5 → 0.72.6.


Generated by Claude Code

…k escape

remove_cached_rejects_path_traversal used a non-hex key ("../../etc"),
which the 64-hex validator (CapsuleKey::parse) refuses BEFORE any path is
built — so the canonicalize + starts_with(cache) containment guard was
never exercised. A valid 64-hex key cannot escape <cache>/modules on its
own, so exercising the guard needs a compromised cache layout: a symlink
inside the cache pointing at a file outside it.

Add remove_cached_containment_guard_refuses_a_symlink_escape (unix): plant
such a symlink and assert a well-formed remove is refused and the outside
file survives. Verified it fails when the guard is deleted (mutation check).
Rename the existing test to remove_cached_rejects_a_non_canonical_key_at_the_validator
so each test names the gate it actually pins.

The sibling concern in #1622 (the availability-batch non-canonical-key test)
is already satisfied: availability_batch_rejects_a_non_canonical_key_without_touching_the_filesystem
now plants a real out-of-cache file and drives .. / ../secret traversals that
collapse onto it, so it is non-vacuous (would answer available:true without
the guard).

Closes #1622

Co-Authored-By: Claude <noreply@anthropic.com>
@MichaelTaylor3d
MichaelTaylor3d merged commit 2daa923 into main Aug 2, 2026
15 checks passed
@MichaelTaylor3d
MichaelTaylor3d deleted the test/1622-containment-guard-coverage branch August 2, 2026 05:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants