Introduces path-guard.ts with guardPath (symlink-aware) and guardPathUnsafe (lexical-only) that throw SandboxEscapeError on any escape attempt. Replaces weak containment checks in file-tools, git-tools, and shell-tools with strict guards. Adds 12 unit tests covering traversal, absolute-path, and sibling-dir escape vectors. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
56 lines
1.6 KiB
Markdown
56 lines
1.6 KiB
Markdown
# P8-016: Security — Tool Path Hardening + Sandbox Escape Prevention
|
|
|
|
## Status: in-progress
|
|
|
|
## Branch: feat/p8-016-tool-hardening
|
|
|
|
## Issue: #169
|
|
|
|
## Scope
|
|
|
|
Harden file, git, and shell tool factories so no path operation escapes `sandboxDir`.
|
|
|
|
## Files to Create
|
|
|
|
- `apps/gateway/src/agent/tools/path-guard.ts` (new)
|
|
- `apps/gateway/src/agent/tools/path-guard.test.ts` (new)
|
|
|
|
## Files to Modify
|
|
|
|
- `apps/gateway/src/agent/tools/file-tools.ts`
|
|
- `apps/gateway/src/agent/tools/git-tools.ts`
|
|
- `apps/gateway/src/agent/tools/shell-tools.ts`
|
|
|
|
## Analysis
|
|
|
|
### file-tools.ts
|
|
|
|
- Has existing `resolveSafe()` function but uses weak containment check (relative path)
|
|
- Replace with `guardPath` (for reads/lists on existing paths) and `guardPathUnsafe` (for writes)
|
|
- Error pattern: return `{ content: [{ type: 'text', text: 'Error: ...' }], details: undefined }`
|
|
|
|
### git-tools.ts
|
|
|
|
- Has `clampCwd()` that silently falls back to sandbox root on escape attempt
|
|
- Replace with strict `guardPath` that throws SandboxEscapeError, caught and returned as error
|
|
- Also need to guard the `path` parameter in `git_diff`
|
|
|
|
### shell-tools.ts
|
|
|
|
- Has `clampCwd()` same silent-fallback approach
|
|
- Replace with strict `guardPath` that throws SandboxEscapeError
|
|
|
|
## Key Design Decisions
|
|
|
|
- `guardPath`: uses `realpathSync.native` to resolve symlinks, requires path to exist
|
|
- `guardPathUnsafe`: lexical only (`path.resolve`), for paths that may not exist yet
|
|
- Both throw `SandboxEscapeError` on escape attempt
|
|
- Callers catch and return error result
|
|
|
|
## Verification
|
|
|
|
- pnpm typecheck
|
|
- pnpm lint
|
|
- pnpm format:check
|
|
- pnpm test
|