Skip to content

Comments

test: add missing tag key/value path traversal tests (#412)#417

Merged
stack72 merged 1 commit intomainfrom
test/tag-path-traversal-412
Feb 21, 2026
Merged

test: add missing tag key/value path traversal tests (#412)#417
stack72 merged 1 commit intomainfrom
test/tag-path-traversal-412

Conversation

@stack72
Copy link
Contributor

@stack72 stack72 commented Feb 21, 2026

Summary

Context

PR #403 added assertPathContained() checks for custom tag keys and tag values inside indexTagBasedData(), but explicitly skipped writing tests because the test helper had no way to inject a UnifiedDataRepository. Without tests, regressions in these security checks (e.g., accidentally removing the re-throw guard in the catch block, or removing the assertPathContained calls) would be completely silent.

What the tests verify

Test 1 — malicious tag key: Creates a Data item with tag { "type": "resource", "../../../malicious": "value" }. Asserts that handleModelCreatedindexModelindexTagBasedData rejects with "Path traversal detected" when the tag key would escape the model directory.

Test 2 — malicious tag value: Creates a Data item with tag { "type": "resource", "safe-key": "../../../malicious" }. Asserts the same rejection when the tag value would escape the tag key directory.

Both tests also implicitly verify the re-throw guard in the catch block of indexTagBasedData(), since the error must propagate through try-catch to reach assertRejects.

Test plan

  • deno run test src/infrastructure/repo/symlink_repo_index_service_test.ts — 19/19 pass
  • deno run test — full suite 1809/1809 pass
  • deno check — passes
  • deno lint — passes
  • deno fmt --check — passes

Closes #412

🤖 Generated with Claude Code

…#412)

PR #403 added assertPathContained() validation for tagKey and tagValue
in indexTagBasedData(), but tests were skipped because the test helper
lacked a UnifiedDataRepository stub. This left the security checks
for custom tag keys and values without regression coverage — a silent
failure risk if the re-throw guard in the catch block or the
assertPathContained calls were ever removed or broken.

This commit closes the gap by:

- Extending createIndexService() to accept an optional
  UnifiedDataRepository, allowing tag-based data indexing to be
  exercised in tests.
- Adding a minimal createStubUnifiedDataRepo() that returns controlled
  Data items from findAllForModel() (with listVersions returning [] so
  the standard type-tag loop completes without side effects).
- Adding two test cases that inject Data items with malicious path
  traversal strings ("../../../malicious") as a custom tag key and tag
  value respectively, and assert that handleModelCreated rejects with
  "Path traversal detected".

Both tests also implicitly verify the re-throw guard in the catch block
of indexTagBasedData(), since the error must propagate through the
try-catch to reach assertRejects.

Closes #412
Copy link

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review Summary

This PR adds two important security tests for path traversal protection in indexTagBasedData(). The tests close a coverage gap identified in #412 by verifying that the assertPathContained() checks added in PR #403 work correctly for custom tag keys and tag values.

Blocking Issues

None.

Code Quality Assessment

TypeScript strict mode: No any types; proper type imports used (type UnifiedDataRepository)

Code style (CLAUDE.md): Named exports used, copyright header present, tests follow foo.tsfoo_test.ts pattern

Domain-driven design:

  • SymlinkRepoIndexService correctly positioned in infrastructure layer
  • UnifiedDataRepository follows repository pattern
  • Data entity used correctly with factory method

Test coverage:

  • Tests verify path traversal protection for malicious tag keys ("../../../malicious": "value")
  • Tests verify path traversal protection for malicious tag values ("safe-key": "../../../malicious")
  • Tests implicitly verify the re-throw guard in the catch block (lines 585-593)

Security: These tests prevent silent regressions in critical path traversal protection code

Test Design Review

The stub implementation is well-designed:

  • findAllForModel() returns controlled test data
  • listVersions() returns [] which is correct since path traversal checks occur before listVersions is called
  • Other methods throw "not implemented" which is appropriate for a focused test stub

The test flow correctly validates:

  1. Malicious tag key → assertPathContained() throws at line 547-551
  2. Malicious tag value → assertPathContained() throws at line 556-560
  3. Path traversal errors propagate through the catch block re-throw guard (lines 588-590)

CI Status

✅ Lint, Test, and Format Check: passed

LGTM! 🔒

@stack72 stack72 merged commit cabb693 into main Feb 21, 2026
4 checks passed
@stack72 stack72 deleted the test/tag-path-traversal-412 branch February 21, 2026 19:36
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.

test: add missing tag key/value path traversal test vectors for symlink_repo_index_service

1 participant