Skip to content

fix: symlink sandbox bypass in isWithinPath (security) — v0.12.10#74

Merged
TheAmericanMaker merged 1 commit into
mainfrom
fix/symlink-sandbox-bypass
Jul 23, 2026
Merged

fix: symlink sandbox bypass in isWithinPath (security) — v0.12.10#74
TheAmericanMaker merged 1 commit into
mainfrom
fix/symlink-sandbox-bypass

Conversation

@TheAmericanMaker

Copy link
Copy Markdown
Member

Security fix

The Pi extension's tool-call sandbox used lexical path comparison () without resolving symlinks. A sub-agent could create a symlink inside pointing to a file outside the allowed root and write through it — the guard would pass because it only checked the lexical path.

Fix

  • Added in — uses before comparison
  • Updated Pi tool_call hook to use instead of
  • MCP server not affected (does not use )
  • 4 regression tests: documents vulnerability, verifies fix, verifies legitimate paths pass

Discovery

Found during the v0.12.9 self-analysis case study. The semantic defect scan (Pass 4: Security & Trust) identified it. Independent reproduction confirmed: a symlink inside an allowed directory pointing outside passes the lexical check but fails the resolved check.

Validation

  • 268/268 tests pass (264 original + 4 new)
  • Build clean

The Pi extension's tool-call sandbox used lexical path comparison (resolve())
without resolving symlinks. A sub-agent could create a symlink inside
.codecarto/ pointing to a file outside the allowed root (e.g. ~/.ssh/id_rsa)
and write through it -- the isWithinPath guard would pass because it only
checked the lexical path, not the resolved target.

Fix: added isWithinPathResolved which uses realpath before comparison.
Updated the Pi tool_call hook to use isWithinPathResolved instead of
isWithinPath. The MCP server was not affected (it does not use isWithinPath).

Regression tests:
- Documents the vulnerability (lexical check returns true for symlink)
- Verifies the fix (resolved check returns false for symlink)
- Verifies legitimate paths still pass
- Verifies the root itself passes

Discovered during the v0.12.9 self-analysis case study, independently
confirmed via reproduction, and fixed with regression coverage.

268/268 tests pass (264 original + 4 new).
@TheAmericanMaker
TheAmericanMaker merged commit f59c9fc into main Jul 23, 2026
5 checks passed
@TheAmericanMaker
TheAmericanMaker deleted the fix/symlink-sandbox-bypass branch July 23, 2026 20:32
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.

1 participant