Uh oh!
There was an error while loading. Please reload this page.
fix: prevent symlink escape in Filesystem.contains - #6403
Conversation
The `Filesystem.contains()` function previously performed only lexical path checking, which could be bypassed using symlinks inside the project directory. An attacker could create a symlink pointing to sensitive files outside the project (e.g., ~/.ssh/id_rsa), and the file tools would allow reading them. This fix: - Uses `realpathSync` to resolve symlinks before checking containment - Falls back to lexical check if realpath fails (e.g., file doesn't exist) - Adds explicit handling for Windows cross-drive paths (D:\ vs C:\) - Removes the TODO comments that documented this issue
There was a problem hiding this comment.
Pull request overview
This PR addresses a critical security vulnerability where the Filesystem.contains() function could be bypassed using symlinks within the project directory, potentially allowing access to sensitive files outside the project boundaries.
Key Changes:
- Implements symlink resolution using
realpathSyncbefore path containment checks - Adds Windows-specific handling for cross-drive path detection
- Removes TODO comments that documented the vulnerability
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| packages/opencode/src/util/filesystem.ts | Enhanced contains() function with symlink resolution via realpathSync and Windows cross-drive path detection |
| packages/opencode/src/file/index.ts | Removed TODO comments about the symlink escape vulnerability that has now been addressed |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
- Extract duplicated Windows cross-drive and relative path check into isContained() helper function - Resolve parent and child paths independently for better security (use resolved parent even when child doesn't exist yet) - Simplifies the code and addresses Copilot review feedback Signed-off-by: Jay Hemnani <jayhemnani9910@gmail.com>
f1ae801 to
08fa7f7CompareClosing this pull request because it has had no updates for more than 60 days. If you plan to continue working on it, feel free to reopen or open a new PR. |
The
Filesystem.contains()function previously performed only lexical path checking, which could be bypassed using symlinks inside the project directory. An attacker could create a symlink pointing to sensitive files outside the project (e.g., ~/.ssh/id_rsa), and the file tools would allow reading them.This fix:
realpathSyncto resolve symlinks before checking containment