Skip to content

[bug]Fix dot-dot-prefixed repo path filtering#1395

Open
stale2000 wants to merge 1 commit into
entireio:mainfrom
stale2000:stale2000/fix-dotdot-path-traversal
Open

[bug]Fix dot-dot-prefixed repo path filtering#1395
stale2000 wants to merge 1 commit into
entireio:mainfrom
stale2000:stale2000/fix-dotdot-path-traversal

Conversation

@stale2000

@stale2000 stale2000 commented Jun 9, 2026

Copy link
Copy Markdown

Entire session log: https://entire.io/gh/stale2000/cli/session/019eaaa8-c4a4-71b2-93d0-e249a631f82c

Issue

Repo-relative path filtering treated any relative path beginning with two dots as path traversal. That is too broad: the path segment .. means parent directory, but names like ..generated, ..cache, or ..schema are ordinary legal filenames/directories when they are inside the repository.

The affected logic showed up in two places:

  • paths.ToRelativePath returned an empty string for any filepath.Rel result with a .. prefix.
  • checkpoint metadata directory walkers rejected the same broad prefix with path traversal detected.

Effects

A valid repo file such as:

/repo/..generated/schema.json

is inside /repo, and Git reports it as repo-relative path:

..generated/schema.json

Before this fix, Entire could treat that path as outside the repo because it starts with ... The practical effects were:

  • ToRelativePath silently returned "", so legal files could be filtered out of checkpoint file tracking.
  • checkpoint metadata writes could fail with a false path traversal detected error.
  • checkpoint data could be incomplete for projects that legitimately use dot-dot-prefixed generated directories.

Simple Reproduction

Create a clean repo with a legal child path that starts with two dots:

tmp=$(mktemp -d)
cd "$tmp"
git init -q
mkdir -p ..generated
printf '{"ok":true}\n' > ..generated/schema.json

git status --porcelain
git ls-files --others --exclude-standard

Git treats the file as in-repo:

?? ..generated/
..generated/schema.json

The old check behaved like this:

rel, _ := filepath.Rel(repoRoot, repoRoot + "/..generated/schema.json")
// rel == "..generated/schema.json"

if strings.HasPrefix(rel, "..") {
    return "" // wrong: this is not traversal
}

The correct distinction is:

../outside.txt              traversal, reject
..                          traversal, reject
..generated/schema.json     legal child path, allow

Fix

This PR centralizes traversal detection in paths.IsRelativeTraversal and makes it segment-aware:

  • reject exactly ..
  • reject paths beginning with ../
  • reject paths beginning with ..\
  • allow names that merely start with two dots, such as ..generated/schema.json

ToRelativePath, IsSubpath, and the checkpoint metadata walkers now use the shared helper instead of repeating broad strings.HasPrefix(rel, "..") checks.

Tests

Added regression coverage for:

  • paths.ToRelativePath preserving ..generated/schema.json
  • traversal detection still rejecting real .. parent segments
  • temporary and committed checkpoint metadata walkers accepting legal dot-dot-prefixed names
  • slash and backslash traversal forms for cross-platform path inputs

Verification

  • go test ./cmd/entire/cli/paths ./cmd/entire/cli/checkpoint
  • local throwaway repo repro confirmed the old logic dropped ..generated/schema.json and the fixed logic preserves it

Related Work

I checked existing issues and PRs. The closest prior work was #1365, which hardened real path traversal through attacker-controlled session/tool/subagent IDs. This PR covers a different bug: false positives for legal repo child paths whose names start with ...

@stale2000 stale2000 requested a review from a team as a code owner June 9, 2026 04:52
@stale2000 stale2000 changed the title Fix dot-dot-prefixed repo path filtering [bug]Fix dot-dot-prefixed repo path filtering Jun 9, 2026
Repo files such as ..generated/schema.json are valid children, but several containment checks treated any relative path beginning with two dots as traversal. Centralize the check so only actual parent-directory segments are rejected, then use that rule in repo-relative conversion and checkpoint metadata walkers.

Constraint: Git and local filesystems allow names that merely start with two dots

Rejected: Keep ad hoc HasPrefix checks | they repeat the original false-positive pattern and drift from IsSubpath

Confidence: high

Scope-risk: narrow

Directive: Keep traversal checks segment-aware; do not reject prefixes like ..generated unless product policy explicitly bans those filenames

Tested: go test ./cmd/entire/cli/paths ./cmd/entire/cli/checkpoint

Tested: local throwaway repo reproduced old ToRelativePath drop and fixed behavior

Not-tested: mise run check after removing unrelated auth fixture change

Entire-Checkpoint: a77f6e131de5
@stale2000 stale2000 force-pushed the stale2000/fix-dotdot-path-traversal branch from 34d53ca to 966164a Compare June 9, 2026 05:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant