security: confine model context reads to the cloned repository - #9
Open
harshitethic wants to merge 4 commits into
Open
harshitethic wants to merge 4 commits into
harshitethic wants to merge 4 commits into
Conversation
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.
Problem
PatchPilot builds the model's repository context by walking the cloned worktree and reading selected files. The existing implementation checked ignored directory names but did not enforce that a discovered path still resolved inside the clone.
That means an untrusted repository could include a file symlink such as:
Path.is_file()follows file symlinks, solist_files()could includeleaked.txt. Later,read_repo_context()openedrepo / "leaked.txt", which follows the same symlink and could place host-side content into the prompt sent to Ollama/OpenAI/OpenRouter.The edit path already had a repository-containment check, but the read/context path did not, so the security boundary was inconsistent.
Fix
Introduce one resolved-path boundary for automatic repository reads:
Internal symlinks that resolve to files inside the repository remain usable. External symlinks and explicit parent-path escapes are excluded.
Regression coverage
Adds focused tests for:
../secret.txtcontext-read attempt;read_repo_context(), proving the second boundary works independently of discovery;Symlink-specific tests skip only on platforms where creating symlinks is unavailable.
Security scope
This PR protects the repository-context → model prompt boundary. It prevents context collection from following repository paths to host files outside the cloned worktree.
It does not claim to sandbox test execution or arbitrary repository code. PatchPilot still needs container/VM isolation, resource limits, network policy, and secret isolation before being exposed to untrusted multi-user workloads; the README continues to state that explicitly.
Documentation
The security model now documents that repository context is restricted to resolved paths inside the clone before contents are sent to the configured model.
Changed files
backend/app/main.py— resolved repository-path validation + guarded discovery/read pathbackend/tests/test_main.py— four regression/behavior testsREADME.md— documented context-confinement guaranteeValidation notes
This branch is based directly on current
mainand is isolated from the other open PatchPilot fixes. The diff is 3 files and keeps the public API unchanged.