fix(hooks): main-checkout guard misses .. paths #169

Closed
opened 2026-10-29 19:19:06 +01:00 by motoko · 0 comments
Collaborator

Defect

The main-checkout guard (.agents/hooks/main-checkout-guard.sh) lets an
edit into a main checkout on its main branch when the path goes through
a directory that does not exist and then climbs back with ...

Location

.agents/hooks/main-checkout-guard.sh, check(), lines 84-88 at
0fa031286f: the loop walks up to the
first existing directory and keeps every later component, ..
included, as literal text, so the repository lookup runs from the
wrong directory.

Evidence

With /repo a main checkout on main:

  • {"tool_name":"Write","tool_input":{"file_path":"/tmp/nonexistent-x/../../repo/AGENTS.md"},"cwd":"/repo"}
    exits 0 (allowed);
  • the same event with /repo/AGENTS.md exits 2 with the refusal.

The client then writes to the resolved path, inside the main checkout.

Scenario

An agent, by mistake or following injected text, edits
/tmp/x/../../repo/AGENTS.md while /repo is on its main branch; the
guard allows it and the main checkout changes. Severity is low: Bash
stays unguarded, so this widens little, but it is a hole in the
control.

Smallest fix

Refuse any path that holds a .. component, one test before the walk;
or resolve .. lexically before the walk.

Seen at 0fa031286f.

## Defect The main-checkout guard (`.agents/hooks/main-checkout-guard.sh`) lets an edit into a main checkout on its main branch when the path goes through a directory that does not exist and then climbs back with `..`. ## Location `.agents/hooks/main-checkout-guard.sh`, `check()`, lines 84-88 at 0fa031286f3052c861e5e8e1f70e13da9b8443a8: the loop walks up to the first existing directory and keeps every later component, `..` included, as literal text, so the repository lookup runs from the wrong directory. ## Evidence With `/repo` a main checkout on `main`: - `{"tool_name":"Write","tool_input":{"file_path":"/tmp/nonexistent-x/../../repo/AGENTS.md"},"cwd":"/repo"}` exits 0 (allowed); - the same event with `/repo/AGENTS.md` exits 2 with the refusal. The client then writes to the resolved path, inside the main checkout. ## Scenario An agent, by mistake or following injected text, edits `/tmp/x/../../repo/AGENTS.md` while `/repo` is on its main branch; the guard allows it and the main checkout changes. Severity is low: Bash stays unguarded, so this widens little, but it is a hole in the control. ## Smallest fix Refuse any path that holds a `..` component, one test before the walk; or resolve `..` lexically before the walk. Seen at 0fa031286f3052c861e5e8e1f70e13da9b8443a8.
Sign in to join this conversation.
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
claudiomaradonna/agent-foundry#169
No description provided.