Skip to content

Hosted yarn classic redirect breaks every install in projects with a yarn-offline-mirror: the mirror's upstream tarball shares the hosted URL's basename and fails the new integrity pin #364

Description

[agent] Found by the scheduled Yarn classic (1.x) bug-hunt routine (ledger #304).

Summary

In a yarn-classic project that uses an offline mirror (yarn-offline-mirror "./mirror" in .yarnrc, the documented way to commit dependencies for offline or air-gapped CI), scan --mode hosted rewrites the lock entry to the hosted tarball and reports success. After that, every install of the project fails.

Yarn 1 names and looks up offline-mirror files by the basename of the resolved URL. The hosted URL …/patch/npm/left-pad/1.3.0/<token>/<uuid>/left-pad-1.3.0.tgz has the same basename, left-pad-1.3.0.tgz, as the upstream tarball already sitting in the mirror. So:

  • yarn install / yarn install --frozen-lockfile (yarn ≥ 1.10) takes the upstream mirror file and checks it against the new patched integrity → Integrity check failed for "left-pad", exit 1.
  • yarn install --offline (yarn ≥ 1.7) → Can't make a request in offline mode ("…/left-pad-1.3.0.tgz"), exit 1, because the patched tarball never reaches the mirror.

The scan prints no warning, and nothing in the docs mentions offline mirrors. Vendored mode on the same project works (the patched file: tarball is installed, online and --offline). Only hosted mode is affected.

Impact

  • Hosted mode, which v5 makes the default, breaks every install, frozen or not and online or offline, for any yarn-classic project with a populated offline mirror. The user gets an integrity error that points at Socket's own URL.
  • The only ways out are hand-deleting the mirror file (and it has to be the right one) or reverting the redirect.
  • A silent success in the scan output (status: success, redirect.redirected: 1, warnings: []).

Repro (Linux, main f6b7fb9, yarn 1.22.22)

mkdir app && cd app
echo '{"name":"b","version":"1.0.0","private":true,"dependencies":{"left-pad":"1.3.0"}}' > package.json
printf 'yarn-offline-mirror "./mirror"\n' > .yarnrc
yarn install                         # mirror/left-pad-1.3.0.tgz (upstream bytes)

socket-patch scan --mode hosted --json --yes --api-url $MOCK --org test-org --api-token fake
#  → status success, redirect.redirected 1, no warnings
#  yarn.lock: resolved "http://…/patch/npm/left-pad/1.3.0/<token>/<uuid>/left-pad-1.3.0.tgz#f6cceb…"
#             integrity sha512-rsCT4g…  (patched tarball)

# fresh checkout of package.json + yarn.lock + .yarnrc + mirror/ + .socket/, empty cache:
yarn install --frozen-lockfile       # exit 1
# error http://…/left-pad-1.3.0.tgz: Integrity check failed for "left-pad"
#   (computed integrity doesn't match our records, got "sha512-XI5MPz… sha1-W4o6d2…")   ← the upstream tarball
yarn install --frozen-lockfile --offline   # exit 1: Can't make a request in offline mode ("…/left-pad-1.3.0.tgz")

Control: the same project with no socket-patch step installs fine from the mirror, both online and --offline (1.7+).

$MOCK is a local mock of the patch API. Its hosted URL uses the production shape (/patch/npm/<name>/<version>/<token>/<uuid>/<name>-<version>.tgz, as in vex.rs / scan/mod.rs tests), so the basename collision also happens against patch.socket.dev.

Expected vs actual

  • Expected: docs/ecosystems.md lists yarn classic as fully supported in hosted mode. After a successful hosted scan, the next install (frozen or not) should install the patched bytes. If a mirror is configured, socket-patch should do one of these: put the patched tarball in the mirror under the basename yarn will look up (replacing or moving aside the upstream file), fail closed with a redirect_yarn_classic_offline_mirror-style warning or refusal and point to --mode vendored, or at least warn. The bug-hunt filing bar treats "a rewrite that makes the next frozen install fail" as a bug.
  • Actual: the lock is rewired with no warning, and every install fails with an integrity error.

OS × version

OS yarn online install (--frozen-lockfile) --offline install control, no socket-patch
Linux 1.0.2 / 1.6.0 n/a: these releases install nothing from a mirror even without socket-patch (exit 0, empty node_modules); a yarn / Node 22 limitation n/a installs nothing
Linux 1.7.0 pass (patched; pre-integrity-line yarn refetches) fail (offline mode) pass
Linux 1.9.4 pass (patched) fail (offline mode) pass
Linux 1.10.1 fail (Integrity check failed) fail pass
Linux 1.17.3 fail fail pass
Linux 1.22.22 fail fail pass
Linux (probe) 1.10.1 / 1.22.22 fail (Integrity check failed) fail pass
macOS (probe) 1.10.1 / 1.22.22 fail (Integrity check failed) fail pass
Windows (probe) 1.10.1 / 1.22.22 fail (Integrity check failed) fail pass

Vendored mode with the same mirror: pass on 1.10.1 and 1.22.22 (online and --offline). Released 4.0.0 behaves the same, so this isn't a recent regression.

Suspect code

  • crates/socket-patch-core/src/patch/redirect/mod.rs:3670 (rewrite_yarn_classic). It only rewrites resolved / integrity and never reads .yarnrc / .npmrc (yarn-offline-mirror), so the mirror isn't considered. grep -ri offline.mirror over the repo finds no handling or documentation.

Probe run (ubuntu/macos/windows × yarn 1.10.1/1.22.22): https://github.com/SocketDev/socket-patch/actions/runs/36761888480

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions