Skip to content

fix(amazonq): keep transform checkpoint changes inside the solution folder - #2969

Open
hezelin-work wants to merge 1 commit into
Amazon-Q-Developer:feature/security-fixes-v2from
hezelin-work:fix/atx-checkpoint-paths
Open

hezelin-work wants to merge 1 commit into
Amazon-Q-Developer:feature/security-fixes-v2from
hezelin-work:fix/atx-checkpoint-paths

Conversation

@hezelin-work

@hezelin-work hezelin-work commented Oct 23, 2026 •

Copy link
Copy Markdown

Problem

Applying a transform checkpoint did not limit changes to the solution folder.

Solution

  • Skip checkpoint entries that are not inside the solution folder once symlinks are resolved, that are symlinks themselves, or that are in the folder that holds the transform job data, and entries that would write to a file with more than one hard link. The transform info response lists the skipped entries in SkippedCheckpointEntries.
  • Apply an entry outside the solution folder only when the job's source files include it. The source files list is now written for every job, not only for interactive ones.
  • Back up a source file outside the solution folder inside the job's backup folder.
  • Download and apply a checkpoint only when its job and step IDs are folder names.

Behavior change: a checkpoint no longer adds files outside the solution folder, or changes files there that are not among the job's source files. Jobs that are not interactive now also keep a source files list, so their checkpoint applies preserve files the customer edited since the last apply, as interactive jobs already do.

Testing: added unit tests.

License

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.

@codecov-commenter

codecov-commenter commented Oct 23, 2026 •

Copy link
Copy Markdown

⚠️ Please install the 'codecov app svg image' to ensure uploads and comments are reliably processed by Codecov.

Codecov Report

❌ Patch coverage is 96.05263% with 12 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
...anguage-server/netTransform/atxTransformHandler.ts 95.90% 10 Missing and 2 partials ⚠️

📢 Thoughts on this report? Let us know!

@hezelin-work
hezelin-work force-pushed the fix/atx-checkpoint-paths branch 2 times, most recently from 37e7c88 to e33ce30 Compare October 23, 2026 06:23
@hezelin-work
hezelin-work marked this pull request as ready for review October 23, 2026 13:06
@hezelin-work
hezelin-work requested a review from a team as a code owner October 23, 2026 13:06

@ashishrp-aws ashishrp-aws left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

🤖 AI-assisted review at e33ce30 (reviewer agent plus a chair re-check).

Requesting changes. The lexical check is right as far as it goes. Every add, remove, update and both sides of a move go through checkpointEntryPath/solutionEntryPath, so .., a/../../x, ..\x, drive and UNC paths and the job-data folder (including case and trailing dot/space variants) are all rejected. But the check only compares paths as text, while the writes follow symlinks.

Blocking

  1. A symlink inside the solution folder escapes the check (atxTransformHandler.ts:4616-4642 check, then copyFileSync/unlinkSync at :4731/4763/4803/4859-4861). Reproduced on a real filesystem with sln/src/link -> ../../outside:

    • updated src/link/victim → copyFileSync overwrote outside/victim
    • removed src/link/del → unlinkSync deleted the outside file
    • a file symlink sln/filelink -> outside/victim → the write went through to the outside file
    • a move with before = src/link/key → outside content was copied into the tree

    Fix: canonicalise the nearest existing ancestor of each destination, delete target and move source (resolveSymlinkAwarePath in toolShared already does this) and check it against realpath(solutionRoot). Also lstat the destination and refuse to write through a symlink. Add a real-fs test with a symlinked directory.

Should fix
2. The checkpoint download path has the same class. step.StepId / stepId come from the server unchecked and are joined into the extraction directory (:2884, :3633-3639). With StepId = "../../../../x", the extraction root itself escapes, and the zip-slip guard only checks against that already-escaped root. Validate step IDs against a strict pattern (e.g. ^[A-Za-z0-9_-]+$) or apply the same containment check to pathToDownload.
3. Skipped entries are silent. They're only logged: success stays true, the counts omit them (:4870), and callers then mark the step applied (:2907, :3660), so it's never retried. Return a skippedEntries list and surface it in the transform status, so the user isn't handed a partial transform without notice.
4. The job-data exclusion compares names, not the folder on disk. UNVERIFIED, since I had no Windows host: the 8.3 short name ARTIFA~1\… and artifactWorkspace::$INDEX_ALLOCATION\… pass the check. The impact stays inside the solution, but such an entry could overwrite the manifest or applied-steps record that the user-edit protection relies on. Compare the canonical destination against realpath(<sln>/artifactWorkspace) instead.

Non-blocking: reject : in path segments on win32 (alternate data streams).

@dungdong-aws
dungdong-aws force-pushed the fix/atx-checkpoint-paths branch from e33ce30 to 68c6a18 Compare October 28, 2026 17:30
@dungdong-aws
dungdong-aws changed the base branch from feature/security-fixes to feature/security-fixes-v2 October 28, 2026 17:30
@hezelin-work
hezelin-work force-pushed the fix/atx-checkpoint-paths branch 4 times, most recently from 3dbf9b1 to bcaf6a1 Compare November 6, 2026 05:57
…older

- Skip checkpoint entries that are not inside the solution folder once
  symlinks are resolved, that are symlinks, or that are in the folder
  that holds the transform job data, and entries that would write to a
  file with more than one hard link. List the skipped entries in the
  transform info response.
- Allow an entry outside the solution folder only when the job's
  source files include it, write the source files list for every job,
  and back up such a file inside the job's backup folder.
- Download and apply a checkpoint only when its job and step IDs are
  folder names.
@hezelin-work
hezelin-work force-pushed the fix/atx-checkpoint-paths branch from bcaf6a1 to ace6e22 Compare November 6, 2026 09:18
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.

3 participants