fix: follow links in the existing part of a path that does not exist yet - #85
Merged
Merged
Conversation
validatePathInsideWorkspace resolved a path through realpath only when the path itself or its parent existed. When neither did - a save directory with folders still to be created - it compared the path as written, resolving nothing. Two things followed: - A link in the existing part of the path that leads out of the workspace went unseen. writeAtomic validates and then creates the folders with mkdir -p, so the folders and the image were created on the far side of the link. - In a workspace opened through a link (a symlinked home directory, macOS's /var, an 8.3 short name on Windows) the workspace side is a real path and the target side was not, so new nested folders were refused as outside. Resolve the nearest ancestor that exists and append the missing segments to it, at any depth. A relative path is now taken from the workspace root on every branch; before, the first attempt resolved it from the process's working directory. The only caller builds absolute paths. The extension runs only in trusted workspaces, so this is a check that did less than it claimed, not an exposure to an untrusted workspace. The new tests build a real tree with a link out of the workspace and a workspace reached through a link. Two of them fail on the previous code: new folders under the outward link were accepted, and new folders under the linked workspace were refused. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Makes the workspace-containment check follow links for paths that do not exist yet, at any depth.
Why
validatePathInsideWorkspaceresolved a path throughrealpathonly when the path itself or its parent existed. When neither did — a save directory with folders still to be created — it compared the path as written and resolved nothing:writeAtomicvalidates and then creates the folders withmkdir -p, so with a save directory likeassets/newwhereassetsis a link to somewhere else, the folders and the image were created on the far side of the link. With the default.clipshot(one level) the parent exists, so the default was not affected./varor an 8.3 short name on Windows, the unresolved target never lined up with it, so a nested save directory that did not exist yet was rejected as outside.The extension runs only in trusted workspaces (
untrustedWorkspaces.supported: false), so this is a check that did less than it claimed rather than an exposure to an untrusted workspace.What changed
resolveExistingPrefixwalks up to the nearest ancestor that exists, resolves it withrealpath, and appends the missing segments. The containment comparison itself is unchanged.path-generator.ts) builds absolute paths.CHANGELOG.md: an[Unreleased]entry under Fixed.Verification
test/security/path-validator-workspace.test.tsbuilds a real directory tree: a link (a junction on Windows) out of the workspace, and a workspace reached through a link. Eight cases, accepting and rejecting.resolved "true" instead of rejecting), and new folders under the linked workspace are refused. The other six pass on both, so they show the tree behaves as the tests assume.npm run lint,npm run compile,npm run typecheck:testand the whole Vitest suite (495 tests) pass locally on Windows; CI runs the new tests on Linux and macOS as well.🤖 Generated with Claude Code