Skip to content

Fix: Path Traversal in File Tools#342

Open
superagent-security[bot] wants to merge 1 commit into
mainfrom
superagent/patch-1b969113-9f7d-48d5-8cf7-fe1fe6d7ebfd
Open

Fix: Path Traversal in File Tools#342
superagent-security[bot] wants to merge 1 commit into
mainfrom
superagent/patch-1b969113-9f7d-48d5-8cf7-fe1fe6d7ebfd

Conversation

@superagent-security

@superagent-security superagent-security Bot commented Jul 2, 2026

Copy link
Copy Markdown

Summary

Add assertInsideWorkspace (realpath + relative() prefix check, covering lexical ../ traversal and symlink escapes) and call it from resolvePath so readFile, writeFile, and editFile reject any path resolving outside the workspace, mirroring the repo's existing assertInsideSchedulesDir guard. Throws on escape so tools return a clean failure instead of touching the host.

Finding

Path Traversal in File Tools

Generated by Superagent from the proposed patch for this finding.


Note

Low Risk
Security-hardening change that only blocks invalid paths; legitimate in-workspace file operations are unchanged.

Overview
Closes a path traversal hole in agent file tools by validating every user-supplied path before read/write/edit.

Adds assertInsideWorkspace, which canonicalizes the workspace root and target with realpathSync (via safeRealpath when resolution fails), then uses relative() to reject paths that escape lexically (../) or via symlinks. It is invoked from resolvePath, so readFile, writeFile, and editFile all fail with a clear error instead of touching files outside the workspace.

Reviewed by Cursor Bugbot for commit 33e1057. Configure here.

@open-cla

open-cla Bot commented Jul 2, 2026

Copy link
Copy Markdown

Contributor License Agreement

All contributors are covered by a CLA.

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 3 potential issues.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Want reviews to match your repository better? Bugbot Learning can learn team-specific rules from PR activity. A team admin can enable Learning in the Cursor dashboard.

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit 33e1057. Configure here.

Comment thread src/tools/file.ts
const realRel = relative(root, realTarget);
if (realRel.startsWith("..") || isAbsolute(realRel)) {
throw new Error(`Path "${filePath}" points outside the workspace via a symlink and was rejected.`);
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Symlink bypass on new paths

High Severity

When the target path does not exist yet, safeRealpath falls back to resolve, which does not follow symlinks in existing parent segments. A path that stays lexically under the workspace can still pass both checks if a directory component is a symlink outside the workspace, so writeFile can create files on the host.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 33e1057. Configure here.

Comment thread src/tools/file.ts
const rel = relative(root, full);
if (rel.startsWith("..") || isAbsolute(rel)) {
throw new Error(`Path "${filePath}" resolves outside the workspace and was rejected.`);
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cwd symlink false rejection

Medium Severity

The workspace root is taken from safeRealpath(cwd) while the candidate path uses resolve(cwd, filePath). path.relative compares string paths and ignores symlinks, so when the agent’s cwd is a symlink into the workspace, valid relative paths can look like ../… and be rejected even though they refer to files inside the workspace.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 33e1057. Configure here.

Comment thread src/tools/file.ts

const rel = relative(root, full);
if (rel.startsWith("..") || isAbsolute(rel)) {
throw new Error(`Path "${filePath}" resolves outside the workspace and was rejected.`);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dot-dot filename false reject

Low Severity

Escape detection uses rel.startsWith(".."), which also matches legitimate relative paths whose first segment is a filename starting with two dots (for example ..foo), so those in-workspace files are rejected incorrectly.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 33e1057. Configure here.

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.

0 participants