feat(gateway): tool path hardening + sandbox escape prevention (P8-016) (#177)
All checks were successful
ci/woodpecker/push/ci Pipeline was successful
All checks were successful
ci/woodpecker/push/ci Pipeline was successful
Co-authored-by: Jason Woltje <jason@diversecanvas.com> Co-committed-by: Jason Woltje <jason@diversecanvas.com>
This commit was merged in pull request #177.
This commit is contained in:
55
docs/scratchpads/p8-016-tool-hardening.md
Normal file
55
docs/scratchpads/p8-016-tool-hardening.md
Normal file
@@ -0,0 +1,55 @@
|
||||
# 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
|
||||
Reference in New Issue
Block a user