Skip to content

Conversation

@androolloyd
Copy link

Summary

Adds path containment checks to glob and grep tools to prevent searches outside the project directory.

Problem

When an AI agent provides a path parameter that resolves outside the project directory (e.g., ~, /Users/username, or ../), the glob and grep tools would happily traverse the entire filesystem. On macOS, this triggers permission dialogs for protected directories like:

  • ~/Library
  • ~/Music
  • ~/Photos
  • ~/Pictures

This is both a security concern and a poor UX (permission dialog spam).

Solution

Mirror the existing sandboxing pattern from bash.ts (line 88) which uses Filesystem.contains() to validate paths:

if (!Filesystem.contains(Instance.directory, searchPath)) {
  throw new Error(`Search path "..." is outside the project directory...`)
}

Changes

  • glob.ts: Add Filesystem import and containment check after path resolution
  • grep.ts: Add path import, Filesystem import, resolve relative paths, and add containment check

Testing

Verified the logic correctly:

  • ✅ Allows searches within project directory
  • ✅ Allows searches in subdirectories
  • ✅ Blocks $HOME directory
  • ✅ Blocks ../ escape attempts
  • ✅ Blocks absolute paths outside project
  • ✅ Blocks protected macOS directories

Related

This fixes the same class of issue that bash tool already handles, bringing glob/grep tools to parity.

@github-actions
Copy link
Contributor

Thanks for your contribution!

This PR doesn't have a linked issue. All PRs must reference an existing issue.

Please:

  1. Open an issue describing the bug/feature (if one doesn't exist)
  2. Add Fixes #<number> or Closes #<number> to this PR description

See CONTRIBUTING.md for details.

@github-actions
Copy link
Contributor

The following comment was made by an LLM, it may be inaccurate:

I found several related PRs that address similar path containment and security concerns:

Related PRs:

  1. PR fix(security): prevent path traversal via symlinks in File.read and File.list #8727 - fix(security): prevent path traversal via symlinks in File.read and File.list

    • Directly related: addresses path traversal security using similar containment patterns
  2. PR fix: prevent path traversal via symlinks and cross-drive paths #8316 - fix: prevent path traversal via symlinks and cross-drive paths

    • Related: part of the broader effort to prevent path traversal vulnerabilities
  3. PR fix: address external_directory gaps and improve symlink checks #7515 - fix: address external_directory gaps and improve symlink checks

    • Related: addresses gaps in directory security checks
  4. PR fix: prevent symlink escape in Filesystem.contains #6403 - fix: prevent symlink escape in Filesystem.contains

    • Related: improves the underlying Filesystem.contains() method that this PR uses

These are not duplicates of PR #8754, but rather part of a coordinated effort to secure path handling across multiple tools and improve the Filesystem.contains() function it relies on.

…roject

Adds path boundary checks to glob and grep tools with two modes:

1. **Default (permission-based)**: When searching outside the project
   directory, prompts user for 'external_directory' permission - matching
   the existing bash tool behavior.

2. **Strict mode**: Set OPENCODE_STRICT_PATH_SANDBOX=true to hard-block
   all searches outside the project directory (for security-sensitive
   environments).

This fixes an issue where AI-initiated searches could traverse protected
macOS directories (Library, Music, Photos, etc.) triggering permission
dialogs without user consent.

Changes:
- flag.ts: Add OPENCODE_STRICT_PATH_SANDBOX flag
- glob.ts: Add external_directory permission check before glob permission
- grep.ts: Add external_directory permission check before grep permission

The implementation mirrors bash.ts (lines 88, 139-146) which already uses
this pattern for directory access outside the project.
@androolloyd androolloyd force-pushed the fix/sandbox-glob-grep-tools branch from 447f553 to e71836c Compare January 16, 2026 01:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant