fix(server): prevent projects.writeFile symlink escapes#1071
fix(server): prevent projects.writeFile symlink escapes#1071pRizz wants to merge 1 commit intopingdotgg:mainfrom
Conversation
|
Important Review skippedAuto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
📝 Coding Plan
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment Tip You can disable the changed files summary in the walkthrough.Disable the |
Closes #1072
What Changed
projects.writeFilenow canonicalizes both the workspace root and the target path before writing, so a path that looks in-workspace lexically cannot escape the project root by traversing a symlinked directory.This also adds a regression test that creates a symlink inside the workspace pointing to an outside directory and verifies the write is rejected without creating the outside file.
Why
The previous check only validated the lexical relative path. That allowed a write like
linked-outside/escape.mdto pass validation whenlinked-outsidewas a symlink to a directory outside the workspace.Related, but distinct: #316 reports a broader issue where WebSocket methods trust arbitrary client-supplied
cwdvalues and can therefore operate in any directory the server can access. This PR addresses a different boundary failure: even when a caller is already operating against a chosen workspace,projects.writeFilecan still escape that workspace by traversing an in-tree symlink. Fixing this PR improves workspace-root enforcement, but it does not fully resolve the broadercwd-validation problem described in #316.Minimal Repro Script
The script below is intentionally not committed in this PR. It is the smallest copy-pasteable repro I found that can be run from the repo root.
mainto prove the bug is present. It should printVERDICT: UNFIXED/VULNERABLEand show that an outside file was created.VERDICT: FIXEDand show that no outside file was created.Checklist
Note
Prevent symlink escapes in
projects.writeFilepath validationresolveCanonicalPathin wsServer.ts to walk up to the nearest existing ancestor and resolve the real path viarealpathSync.native, catching symlink indirections.resolveWorkspaceWritePathto compare canonical paths for both the workspace root and the target, rejecting writes that resolve outside the project root.projects.writeFilerequests whose resolved path escapes the workspace root now fail with an error instead of writing the file.Macroscope summarized aa2c93b.