Skip to content

fix(install): verify modern Yarn hashes against the CLI binary - #2227

Open
leslieeilsel wants to merge 2 commits into
voidzero-dev:mainfrom
leslieeilsel:agent/yarn-corepack-hash
Open

fix(install): verify modern Yarn hashes against the CLI binary#2227
leslieeilsel wants to merge 2 commits into
voidzero-dev:mainfrom
leslieeilsel:agent/yarn-corepack-hash

Conversation

@leslieeilsel

Copy link
Copy Markdown

Summary

  • verify Yarn 2+ packageManager hashes against the extracted bin/yarn.js, matching Corepack
  • re-verify the same binary when using an existing Vite+ package-manager cache
  • preserve tarball hash verification for npm, pnpm, and Yarn Classic

Why

Corepack writes Yarn 2+ integrity pins from the extracted CLI binary, while Vite+ previously compared them with the npm tarball hash. This made valid Corepack pins fail with a cold Vite+ cache and appear to pass with a warm cache because the cached artifact was not re-verified.

Fixes #2209

Test Plan

@netlify

netlify Bot commented Jul 23, 2026

Copy link
Copy Markdown

Deploy Preview for viteplus-preview canceled.

Name Link
🔨 Latest commit 35de2cb
🔍 Latest deploy log https://app.netlify.com/projects/viteplus-preview/deploys/6a78944b4a1cef0007dddc7c

@leslieeilsel
leslieeilsel force-pushed the agent/yarn-corepack-hash branch 2 times, most recently from f7cdc8f to 26615d1 Compare August 5, 2026 13:19
@leslieeilsel
leslieeilsel marked this pull request as ready for review August 7, 2026 09:03
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, you can upgrade your account or add credits to your account and enable them for code reviews in your settings.

Copy link
Copy Markdown
Author

Local verification results (run on macOS, nightly-2026-08-02)

Since the CI workflows are waiting for maintainer approval, I ran the checks locally on commit 26615d1:

  • cargo test -p vp_pm_cli --lib734 passed, 0 failed (2 ignored), including package_manager::tests and request::tests
  • cargo fmt --check — clean
  • cargo clippy -p vp_pm_cli --lib -- -D warnings — no warnings

One note: the PR description's Test Plan references vite_install, but the changed crate is vp_pm_cli (the commands above use the actual crate name).

Could a maintainer please approve the workflow runs? Thanks! 🙏

@leslieeilsel
leslieeilsel force-pushed the agent/yarn-corepack-hash branch from 07ce1cf to c3609f2 Compare August 7, 2026 09:18
@fengmk2

fengmk2 commented Aug 9, 2026

Copy link
Copy Markdown
Member

@leslieeilsel Can you convert the reproduction steps described in #2209 into a snapshot test? This would ensure that this issue continues to be validated.

@fengmk2 fengmk2 self-assigned this Aug 9, 2026
Added verification for Yarn binary hash for modern Yarn installations. Updated download logic to handle Yarn 2+ package manager correctly.

Signed-off-by: Leslie Lau <1178273431@qq.com>
@leslieeilsel
leslieeilsel force-pushed the agent/yarn-corepack-hash branch from c3609f2 to 35de2cb Compare August 9, 2026 14:52
@leslieeilsel

Copy link
Copy Markdown
Author

Thanks for the suggestion — I’ve added CLI snapshot coverage based on #2209’s cold-cache reproduction. It uses the exact Corepack-generated Yarn 4.17.1 pin, runs vp install, and verifies that the extracted bin/yarn.js is cached.

I also added a vp run case covering both cold and warm cache behavior from the issue follow-up. Both snapshot cases pass locally in record and compare modes.

@fengmk2

fengmk2 commented Aug 10, 2026

Copy link
Copy Markdown
Member

@codex review

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 35de2cb5d9

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +917 to +918
if is_modern_yarn {
verify_yarn_binary_hash(&extracted_package_dir, expected_hash).await?;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Retry failed Yarn binary integrity checks

When a registry or CDN returns a successfully extractable archive whose yarn.js is corrupted, this check returns HashMismatch only after download_and_extract_tgz_with_hash has completed, bypassing that helper's retry loop even though it explicitly treats hash mismatches as retryable download failures. Consequently, a transient bad response immediately aborts an otherwise valid Yarn installation; include the binary verification in the retried download pipeline or apply equivalent retries around this check.

Useful? React with 👍 / 👎.

let tmp_dir = tempfile::tempdir_in(parent_dir)?;
let target_dir_tmp = tmp_dir.path().to_path_buf();

let archive_hash = if is_modern_yarn { None } else { expected_hash };

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Do not extract unauthenticated Yarn archive entries

When the configured npm registry or its delivery path is compromised, clearing the archive hash here lets an attacker supply a tarball containing the correctly pinned bin/yarn.js plus arbitrary unauthenticated entries. The code extracts the entire archive before checking only yarn.js; for example, a bin/yarn symlink to an absolute user-writable path survives verification and create_shim_files later writes the generated shim through it, allowing arbitrary file overwrite. Extract only the authenticated CLI entry into a clean layout, as Corepack does, or independently authenticate the complete archive before installing it.

Useful? React with 👍 / 👎.

Comment on lines +874 to +875
if is_modern_yarn {
verify_yarn_binary_hash(&install_dir, expected_hash).await?;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Verify cached Yarn before global shim dispatch

When a project invokes yarn or yarnpkg directly through the global Vite+ shim and that version is already cached, resolve_matching_package_manager_tool in crates/vp_global_cli/src/shim/dispatch.rs returns the existing executable at lines 690-697 without calling download_package_manager. This new warm-cache check therefore never runs on that primary command path, so a corrupted or replaced yarn.js is executed despite the project's integrity pin; route hash-pinned modern Yarn through verification before taking the shim fast path.

AGENTS.md reference: AGENTS.md:L182-L182

Useful? React with 👍 / 👎.

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.

vp install rejects a Corepack-written packageManager pin: vp hashes the .tgz, Corepack hashes the extracted binary

2 participants