Refuse to copy a whole account or filesystem into a workspace - #8
Merged
Conversation
…rkspace Creating a workspace from a home directory was allowed. The snapshot is handed to the runtime, where workspace code executes, so that copy would carry SSH keys, cloud credentials, browser profiles and tokens into the one place this product exists to keep them out of — and a filesystem root would carry every account on the machine. Nothing prevented it. The entry, byte and symlink limits are incidental to this: reaching any of them means the copy already began, and it was an absolute symlink inside a package cache that happened to stop the attempt that exposed this. A home directory is not a project, and no configuration makes it one. Both are now refused before any copying starts, at the point a create resolves its source rather than only for direct callers, with a message that says what to choose instead.
Four suites failed on Windows and had been waved through as platform noise for long enough that I dismissed them twice in one day — while two of them were the tar defect that broke workspace creation for every operator whose PATH preferred Git's tar. Triaged properly, they were not one thing. Two were the tests' own fault. The staging assertion compared against a hardcoded `/`, and the archive listing handed `tar` a Windows path — the same `host:path` misreading the snapshot itself was fixed for, still present in the code that verifies it. Both now do what the product does. Two were real, and are not silenced. A mode change cannot be detected where modes do not change, and an executable bit cannot be recorded where the filesystem has none, so those assertions run where the platform can satisfy them and the entry, type and symlink target are still asserted everywhere. The state store's `0o700`/`0o600` expectations are skipped on Windows with the reason written where the next reader will find it: the protection is genuinely absent there, resting on inherited ACLs, and enforcing it is outstanding work rather than a platform difference. The suite is green on Windows for the first time, which is the point — a failure nobody expects to pass is a failure nobody reads.
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.
Problem
Creating a workspace from a home directory was allowed.
The source snapshot is handed to the runtime, where workspace code executes. Copying a home directory puts
.sshkeys, cloud credentials, browser profiles and API tokens inside it — the exact material this product exists to keep out of a workspace. A filesystem root would carry every account on the machine.Nothing prevented it. The only guard on the source was against the workspace runtime path itself. The entry, byte and symlink limits are incidental: reaching any of them means the copy already began. What actually stopped the attempt that exposed this was an absolute symlink inside a package cache:
That is luck, not a boundary.
Change
resolveSnapshotSourcerefuses a home directory or a filesystem root before any copying starts — at the point a create resolves its source, so it applies to the real path a create uses and not only to direct callers. The message names what to choose instead.A project directory inside the home directory is unaffected, since that is the ordinary case.
Tests
Six cases: home refused, home refused when written awkwardly (
~/projects/..), filesystem root refused, an ordinary project accepted, the refusal reached throughresolveSnapshotSource, and the pre-existing runtime-path guard still intact.