fix(storage): reject path-traversal artifact ids from untrusted slug_hint - #671
Merged
plind-junior merged 1 commit intoJul 30, 2026
Conversation
kai392
force-pushed
the
fix/critical-issue-artifact-id-path-traversal
branch
from
July 30, 2026 19:42
b2f0d99 to
438cbce
Compare
Author
|
@coderabbitai review |
kai392
force-pushed
the
fix/critical-issue-artifact-id-path-traversal
branch
from
July 30, 2026 20:03
438cbce to
1b79a78
Compare
plind-junior
enabled auto-merge
July 30, 2026 20:03
auto-merge was automatically disabled
July 30, 2026 20:11
Head branch was pushed to by a user without write access
kai392
force-pushed
the
fix/critical-issue-artifact-id-path-traversal
branch
5 times, most recently
from
July 30, 2026 20:26
7b09baa to
7a27ed6
Compare
Co-authored-by: Cursor <cursoragent@cursor.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
KBStore._yaml/_page_path/_source_dirjoined attacker-controlled artifact ids straight into filenames.propose_*takesslug_hintverbatim as the id, and Claim/Page/Entity/Relation models do not constrainidthe waySource.idis hex-locked. Approvingslug_hint="../../../../evil"(or a Windows absolute path) wrote an artifact outside.vouch/, defeating the review gate._validate_artifact_idat the single path-builder chokepoint (same class of guard asbundle._unsafe_name_reason/read_under_root). Reject empty ids, path separators, NUL, absolute prefixes,./.., and..path segments before any file is created. Covers MCP, JSONL, CLI, and directKBStorecallers.ev-ids are unaffected.Prior attempts (#171, #301, #138, #150, #187) were closed as stale or overscoped; the bug is still present on
test. This PR is the minimal storage-only fix with regression tests.Test plan
test_put_rejects_path_traversal_ids— parametrized over../, separators, absolute,./.., NUL, emptytest_validate_artifact_id_rejects_non_stringtest_approve_with_traversal_slug_hint_writes_nothing— end-to-end propose+approve must not create the escaped targettests/test_storage.pygreen locallyRisk / tradeoffs
slug_hintwill fail at approve withValueErrorinstead of writing outside the KB (correct failure mode).