Skip to content

fix: reject /add of files in a sibling dir sharing the root's name prefix#5392

Open
nolanchic wants to merge 1 commit into
Aider-AI:mainfrom
nolanchic:fix/cmd-add-sibling-prefix-leak
Open

fix: reject /add of files in a sibling dir sharing the root's name prefix#5392
nolanchic wants to merge 1 commit into
Aider-AI:mainfrom
nolanchic:fix/cmd-add-sibling-prefix-leak

Conversation

@nolanchic

Copy link
Copy Markdown

Problem

/add <absolute_path> could add a file that lives outside the repo root into the chat (and therefore into the LLM context) whenever the file lived in a sibling directory whose name started with the repo root's name.

Example: with the repo rooted at /tmp/x/repo, the following was accepted:

/add /tmp/x/repoXYZ/secret.env

because /tmp/x/repoXYZ/secret.env.startswith(/tmp/x/repo) is True (string prefix, no path separator).

This is the same class of out-of-tree leak that #178 addressed, but on the literal absolute-path branch of cmd_add — the glob branch (glob_filtered_to_repo) was already protected by Path.is_relative_to(), so the gap only showed up for explicit absolute paths / autocomplete-provided paths.

Root cause

aider/commands.py, inside cmd_add's containment guard:

if (
    not abs_file_path.startswith(self.coder.root)   # str prefix, no separator
    and not is_image_file(matched_file)
    and self.coder.auto_commits
):

self.coder.root has no trailing path separator, so startswith matches any sibling directory whose name shares the root's prefix.

Fix

Use a real path-containment check, matching what glob_filtered_to_repo already does:

if (
    not Path(abs_file_path).is_relative_to(self.coder.root)
    and not is_image_file(matched_file)
    and self.coder.auto_commits
):

Path.is_relative_to is available on all supported Python versions (3.10+).

Test plan

  • Added test_cmd_add_abs_path_in_sibling_dir_with_prefix — reproduces the leak on the old code (fails on main) and passes after the fix.
  • pytest tests/basic/test_commands.py — full file green (70 tests), including the existing out-of-root / absolute-path / read-only-external tests (test_cmd_add_from_outside_root, test_cmd_add_abs_filename, test_cmd_add_read_only_with_external_file, …).
  • pre-commit run --files aider/commands.py tests/basic/test_commands.py — isort / black / flake8 / codespell all pass.

Relates to #178.

…efix

The within-root guard in cmd_add used str.startswith() against the repo
root, which carries no trailing path separator. An absolute path like
/tmp/x/repoXYZ/secret.env was therefore accepted as "within" a repo
rooted at /tmp/x/repo, so an out-of-tree file could be added to the chat
and sent to the LLM.

Use Path.is_relative_to() instead, matching the containment check the
glob branch already performs in glob_filtered_to_repo.

Adds a regression test covering the literal absolute-path branch.

Relates to Aider-AI#178.
@CLAassistant

CLAassistant commented Jul 4, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

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