GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — Yarn berry hosted and vendored scans miss a `file:`/URL copy of the patched package locked under another dependency name, so lockfile VEX (and vendored VEX after install) attests not_affected while that copy installs unpatched · Issue #939 · SocketDev/socket-patch

Yarn berry hosted and vendored scans miss a file:/URL copy of the patched package locked under another dependency name, so lockfile VEX (and vendored VEX after install) attests not_affected while that copy installs unpatched #939

New issue
Copy link
New issue
Copy link
Closed
#1489
Closed
Yarn berry hosted and vendored scans miss a file:/URL copy of the patched package locked under another dependency name, so lockfile VEX (and vendored VEX after install) attests not_affected while that copy installs unpatched#939
#1489
Copy link
Labels
agent:triagedbugSomething isn't workingSomething isn't workingbughuntFound by a scheduled package-manager bug-hunt agentFound by a scheduled package-manager bug-hunt agentpm:yarn-berryYarn Berry (2+)Yarn Berry (2+)priority:p2

Description

@mikolalysenko
Mikola Lysenko (mikolalysenko)
opened on Oct 6, 2026
Issue body actions

[agent] Found by the scheduled Yarn Berry (2+) bug-hunt routine (ledger #305).

Summary

A yarn 4 workspace has member a that depends on left-pad@^1.3.0 from the registry. Member b depends on a copy of the same [email protected] under another dependency name: "lp2": "file:../../forks/left-pad-1.3.0.tgz", a file: directory, or the registry tarball URL https://registry.npmjs.org/left-pad/-/left-pad-1.3.0.tgz. Yarn locks that copy as lp2@file:… / lp2@https://…, with version: 1.3.0, and installs it as node_modules/lp2, whose package.json says [email protected].

  • scan --mode hosted and scan --mode vendored pin only the registry entry. Both exit 0 with status success and no warning about the lp2 copy.
  • A lockfile-only vex then attests pkg:npm/[email protected] as not_affected (inline_mitigations_already_exist) in both modes.
  • After a real fresh yarn install --immutable, node_modules/lp2/index.js is the unpatched upstream file. Hosted vex is honest at this point (not_applied, exit 1). Vendored vex still attests not_affected, exit 0, with only vendored_tree_out_of_sync ("re-run your package manager's install to resync it"). Re-running the install can't fix this, because the lp2 copy never goes through the resolutions pin.

When the copy uses the same name ("left-pad": "file:…" in member b), both modes handle it correctly. Hosted refuses with redirect_yarn_berry_unsupported_protocol + redirect_yarn_berry_shared_descriptor, and vendored refuses with vendor_override_conflict. The gap is only that every guard keys on the lock entry's ident (left-pad@…). For a non-registry protocol, yarn takes the ident from the dependency name (lp2), even though the installed package is [email protected].

This is the berry side of #935 (pnpm), #921 (yarn classic) and #497 (bun). Those issues cover a same-name copy, which berry already refuses. For berry, only the other-name copy gets through.

Impact

The VEX document (the CI / compliance artefact) says the product isn't affected, while the product ships an unpatched copy of exactly the patched name@version. An SCA scanner reading node_modules/lp2/package.json flags it as [email protected]. Neither scan says anything about that copy.

Repro (yarn 4.18.1, main 9c43dfc)

# Mock patch API on :8790 serving pkg:npm/[email protected] (batch, by-package, view, patches/package with a
# tarball + yarn-berry-zip/yarnBerry10c0 artifact, and the hosted tarball), same contract as
# crates/socket-patch-cli/tests/e2e_redirect_yarn_berry_build.rs. Patched tgz = upstream with a marker line on index.js.
mkdir -p proj/packages/a proj/packages/b proj/forks && cd proj
npm pack [email protected] && mv left-pad-1.3.0.tgz forks/          # unmodified upstream
echo '{"name":"root","version":"1.0.0","private":true,"workspaces":["packages/*"]}' > package.json
echo '{"name":"a","version":"1.0.0","dependencies":{"left-pad":"^1.3.0"}}' > packages/a/package.json
echo '{"name":"b","version":"1.0.0","dependencies":{"lp2":"file:../../forks/left-pad-1.3.0.tgz"}}' > packages/b/package.json
printf 'nodeLinker: node-modules\n' > .yarnrc.yml
yarn install
socket-patch scan --mode hosted --json --yes --api-url http://127.0.0.1:8790 --org org --api-token x --patch-server-url http://127.0.0.1:8790
#   exit 0, status success, redirect.warnings: []
# fresh checkout (no node_modules):
socket-patch vex --json --output vex.json --patch-server-url http://127.0.0.1:8790 --api-url http://127.0.0.1:8790 --org org --api-token x
#   exit 0: pkg:npm/[email protected] not_affected (inline_mitigations_already_exist)
YARN_ENABLE_IMMUTABLE_INSTALLS=1 yarn install --immutable           # cold global cache: exit 0
head -1 node_modules/left-pad/index.js   # /* SOCKET-PATCHED */
head -1 node_modules/lp2/index.js        # upstream header: UNPATCHED
node -p "require('./node_modules/lp2/package.json').name"   # left-pad (version 1.3.0)

The copy's lock entry, which every reader skips:

"lp2@file:../../forks/left-pad-1.3.0.tgz::locator=b%40workspace%3Apackages%2Fb":
  version: 1.3.0
  resolution: "lp2@file:../../forks/left-pad-1.3.0.tgz#../../forks/left-pad-1.3.0.tgz::hash=5c8e4c&locator=b%40workspace%3Apackages%2Fb"

Vendored is the same with --mode vendored: it writes resolutions: {"left-pad": "file:./.socket/vendor/npm/<uuid>/left-pad-1.3.0.tgz"}, which yarn doesn't apply to the lp2 ident.

Expected vs actual

  • Expected: CLI_CONTRACT.md ("Contested locks", line 380): when another entry of the same lock resolves the wired name@version from a non-Socket source, "the package manager installs both entries, and that copy stays unpatched", so the reference is dropped with patched_ref_unattributable. The scans should name the unreached copy, as they already do for a same-name file: copy (redirect_yarn_berry_unsupported_protocol, vendor_override_conflict).
  • Actual: neither scan warns. Lock-only vex attests not_affected in both modes, and vendored vex still attests after a fresh --immutable install.

OS × version

Linux, Node 22, real yarn from @yarnpkg/cli-dist, nodeLinker: node-modules, cold global cache for each --immutable install, fresh copy of the tree. Every cell was run at least once; 4.18.1 file:-tgz/hosted was run twice.

yarn lp2 spec Mode Scan warns? Lock-only vex --immutable node_modules/lp2 vex after install
4.18.1 file: tgz hosted no not_affected ok unpatched declines (not_applied)
4.18.1 file: tgz vendored no not_affected ok unpatched not_affected
4.18.1 file: dir hosted no not_affected ok unpatched declines
4.18.1 file: dir vendored no not_affected ok unpatched not_affected
4.18.1 registry tarball URL hosted no not_affected ok unpatched declines
4.18.1 registry tarball URL vendored no not_affected ok unpatched not_affected
4.0.2 tgz / dir / URL hosted no not_affected ok unpatched declines
4.0.2 tgz / dir / URL vendored no not_affected ok unpatched not_affected
4.18.1 (control) "left-pad": "file:…" (same name) hosted / vendored refused loudly n/a n/a n/a n/a

I didn't probe macOS or Windows. This run couldn't use probe branches, and the behaviour lives in lock parsing, which isn't OS-specific. Yarn 2/3 are refused by both modes anyway.

First bad version: none bisected. Release 4.0.0 has no manifest-less lockfile VEX, so this isn't a regression of a shipped feature.

Suspect code

  • crates/socket-patch-core/src/vex/discover/yarn.rs:403: a file: / http locator that isn't Socket's returns silently (no resolved_elsewhere, nothing that contests the ref). Even the URL variant names left-pad/-/left-pad-1.3.0.tgz in the locator, and the file: tarball and directory are in the checkout, so a lock-only reader can tell that lp2 is [email protected].
  • crates/socket-patch-core/src/patch/redirect/mod.rs:~3841 (redirect_yarn_berry_unsupported_protocol / shared_descriptor) and crates/socket-patch-core/src/vendor/yarn_berry_lock.rs:1297 (vendor_override_conflict) only look at entries whose ident is the patched name, so the other-name copy isn't seen.
  • Vendored vex treats the mismatch as vendored_tree_out_of_sync and attests from the committed artifact. Its remedy ("re-run your package manager's install") can't help with a copy the resolutions pin never reaches.

Activity

  1. Mikola Lysenko (mikolalysenko)
    added
    bugSomething isn't workingSomething isn't working
    bughuntFound by a scheduled package-manager bug-hunt agentFound by a scheduled package-manager bug-hunt agent
    pm:yarn-berryYarn Berry (2+)Yarn Berry (2+)
    agent:triaged
    priority:p1
    on Oct 6, 2026
  2. mikolalysenko commented on Oct 6, 2026

    @mikolalysenko
    Mikola Lysenko (mikolalysenko)
    on Oct 6, 2026
    CollaboratorAuthor
    More actions

    [agent] Shares root cause with #935, #938: VEX discovery has no shared same-lock rule for an unpatched copy of the wired name@version. contest_across_locks (vex/discover/mod.rs:606) skips same-file evidence, and the berry extractor (vex/discover/yarn.rs:403) drops a non-Socket file: / URL locator without recording it as a copy of [email protected]. Will be fixed together. The missing hosted/vendored scan warnings for the other-name copy are a separate berry rewriter gap and may be split out.


    Generated by Claude Code

  3. mikolalysenko commented on Oct 6, 2026

    @mikolalysenko
    Mikola Lysenko (mikolalysenko)
    on Oct 6, 2026
    CollaboratorAuthor
    More actions

    [agent] Claiming this issue (with #935, #938; shared root cause: VEX discovery has no shared same-lock rule that lets an unpatched copy of the wired name@version contest the ref). Branch: agent/fix-same-lock-unpatched-copy-vex. Claim-ID: 2026-10-06T13:22:24Z-2c1fea


    Generated by Claude Code

  4. Mikola Lysenko (mikolalysenko)
    added
    agent:claimed
    on Oct 6, 2026
  5. mikolalysenko commented on Oct 6, 2026

    @mikolalysenko
    Mikola Lysenko (mikolalysenko)
    on Oct 6, 2026
    CollaboratorAuthor
    More actions

    [agent] Draft PR: #940


    Generated by Claude Code

  6. Mikola Lysenko (mikolalysenko)
    added a commit that references this issue on Oct 6, 2026

    Stop VEX attesting beside an unpatched lock copy

    918a9ce
  7. mikolalysenko commented on Oct 6, 2026

    @mikolalysenko
    Mikola Lysenko (mikolalysenko)
    on Oct 6, 2026
    CollaboratorAuthor
    More actions

    [agent] #940 fixes the VEX half: a non-Socket file: tarball / directory or registry-url copy locked under another name (lp2@…) is now read for its real package. When that package is the wired name@version, the ref is dropped with patched_ref_unattributable, both lock-only and through the vendored ledger (rule 11). The PR says Refs #939 rather than Fixes. The hosted / vendored berry scans still don't warn about the other-name copy. That gap is in the berry rewriters (redirect_yarn_berry_*, vendor_override_conflict key on the ident), so this issue stays open for it.


    Generated by Claude Code

  8. mikolalysenko commented on Oct 6, 2026

    @mikolalysenko
    Mikola Lysenko (mikolalysenko)
    on Oct 6, 2026
    CollaboratorAuthor
    More actions

    [agent] Yarn Berry bug-hunt run 25 (ledger #305) ran the #939 neighbours against main 9c43dfc and PR #940 head 980b7b6 (yarn 4.0.2 and 4.18.1, Linux). The fixture is the same as before: root "left-pad": "^1.3.0", and member packages/a takes a second copy of [email protected] under the name lp2. The patch is hosted or vendored, and every result comes from a real yarn install and a fresh-checkout cold yarn install --immutable.

    lp2 descriptor (lock entry) scan warning lock-only vex, main lock-only vex, PR #940 post-install vex, PR #940 (installed lp2 is unpatched in every row)
    file:../../vend/lp.tgz, node-modules (control) none not_affected dropped, patched_ref_unattributable ✅ dropped ✅
    file: tgz, pnpm linker none not_affected (hosted post-install attests too) dropped ✅ dropped ✅
    portal:../../vend/lp (lp2@portal:…, version: 0.0.0-use.local) none not_affected not_affected not_affected (hosted and vendored)
    link:../../vend/lp none not_affected not_affected not_affected (hosted and vendored)
    github:stevemao/left-pad#v1.3.0 (lp2@https://github.com/stevemao/left-pad.git#commit=eb115f2…, version: 1.3.0) none not_affected not_affected hosted: not_applied (declines); vendored: not_affected (with vendored_tree_out_of_sync warning)

    Both yarn versions behave the same; I checked 4.0.2 lock-only for portal and github in hosted and vendored mode.

    Notes:

    • portal:/link: resolve to a directory that PR Fix VEX attesting beside an unpatched same-lock copy (#935, #938, #939) #940 could read the same way it reads a file: directory (package.json relative to the locator= workspace). Right now the identical bytes count as a copy when they're spelled file: and don't when they're spelled portal:/link:. docs/ecosystems.md treats link:/portal: targets as first-party source for agent apply (agent mode leaves vend/lp alone, and its vex also attests). It's your call whether a portal:/link: to a byte-identical upstream [email protected] should contest the ref.
    • The git copy's lock entry carries version: 1.3.0 but no package name, so PR Fix VEX attesting beside an unpatched same-lock copy (#935, #938, #939) #940 leaves it alone ("a copy whose package can't be read is left alone"). That fails open: lock-only VEX attests while require('lp2') loads unpatched left-pad 1.3.0.
    • None of the hosted or vendored scans warn about any of these copies (the rewriter half this issue keeps open for).

    Repro (hosted, portal):

    mkdir -p packages/a vend && npm pack [email protected] && tar xzf left-pad-1.3.0.tgz -C vend && mv vend/package vend/lp
    echo '{"name":"root","private":true,"workspaces":["packages/*"],"dependencies":{"left-pad":"^1.3.0"}}' > package.json
    echo '{"name":"a","version":"1.0.0","dependencies":{"lp2":"portal:../../vend/lp"}}' > packages/a/package.json
    echo 'nodeLinker: node-modules' > .yarnrc.yml && yarn install
    socket-patch scan --mode hosted --yes            # no warning about lp2
    socket-patch vex --product pkg:npm/[email protected] -O v.json   # not_affected, also on PR #940
    yarn install --immutable && head -1 node_modules/lp2/index.js   # unpatched

    Generated by Claude Code

  9. Mikola Lysenko (mikolalysenko)
    added a commit that references this issue on Oct 7, 2026

    Fix VEX attesting beside an unpatched same-lock copy (#935, #938, #939)…

    c5be5d1
  10. mikolalysenko commented on Oct 7, 2026

    @mikolalysenko
    Mikola Lysenko (mikolalysenko)
    on Oct 7, 2026
    CollaboratorAuthor
    More actions

    [agent] Yarn Berry bug-hunt run 29 (ledger #305): I re-checked this on main 05ecc6e, which includes #940 as merged, with yarn 4.18.1 on Linux and a hosted pin. Main now gives the same results as the PR head in my run-25 table:

    • lp2@file:../../vend/lpx.tgz (a copy of the patched name@version): lock-only vex drops the ref (patched_ref_unattributable, exit 2). ✅
    • lp2@portal:../../vend/lp: lock-only vex still attests not_affected (exit 0), while yarn install --immutable installs node_modules/lp2 unpatched.
    • Neither hosted scan warns about lp2.

    So the portal:/link: question and the missing rewriter warning are still open, as this issue says.


    Generated by Claude Code

  11. mikolalysenko commented on Oct 8, 2026

    @mikolalysenko
    Mikola Lysenko (mikolalysenko)
    on Oct 8, 2026
    CollaboratorAuthor
    More actions

    [agent] Janitor: releasing the stale claim Claim-ID: 2026-10-06T13:22:24Z-2c1fea. Its PR #940 merged on 2026-10-07 (c5be5d18) as Refs #939, fixing only the VEX half. No follow-up PR exists and the claimer has been silent for more than 48h. The issue stays open for the berry rewriter warning for the other-name copy and the portal:/link: VEX case, and any fixer can claim it.


    Generated by Claude Code

  12. Mikola Lysenko (mikolalysenko)
    removed
    agent:claimed
    on Oct 8, 2026
  13. Mikola Lysenko (mikolalysenko)
    added a commit that references this issue on Oct 9, 2026

    Stop yarn classic VEX attesting a renamed copy

    79529be
  14. Mikola Lysenko (mikolalysenko)
    added
    priority:p2
    and removed
    priority:p1
    on Oct 9, 2026
  15. mikolalysenko commented on Oct 9, 2026

    @mikolalysenko
    Mikola Lysenko (mikolalysenko)
    on Oct 9, 2026
    CollaboratorAuthor
    More actions

    v5 triage: P2, not a release blocker. Retain the remaining portal/link and missing-warning cases at P2. PR #940 already fixed the file/URL VEX part of the original report.

    This follows the maintainer's release scope: one normally completing CLI instance, prioritizing valid-lockfile patch/install behavior, compatibility, and actionable CLI UX.

  16. mikolalysenko commented on Oct 13, 2026

    @mikolalysenko
    Mikola Lysenko (mikolalysenko)
    on Oct 13, 2026
    CollaboratorAuthor
    More actions

    [agent] Claiming this issue (with #1236; shared root cause: which package a renamed yarn file:/url copy really installs is read only by VEX discovery, so the hosted and vendored yarn classic/berry scans never warn about it). Branch: agent/fix-yarn-renamed-copy-identity. Claim-ID: 2026-10-13T15:21:24Z-8ce32a


    Generated by Claude Code

  17. Mikola Lysenko (mikolalysenko)
    added
    agent:claimed
    on Oct 13, 2026
  18. mikolalysenko commented on Oct 13, 2026

    @mikolalysenko
    Mikola Lysenko (mikolalysenko)
    on Oct 13, 2026
    CollaboratorAuthor
    More actions

    [agent] Draft PR: #1489


    Generated by Claude Code

  19. Mikola Lysenko (mikolalysenko)
    added 3 commits that reference this issue on Oct 13, 2026

    Read renamed yarn copies through one helper

    d59c046

    Warn about renamed yarn copies in hosted scans

    376b475

    Warn about renamed yarn copies when vendoring

    83dabb8
  20. Mikola Lysenko (mikolalysenko)
    closed this as completedin #1489on Oct 13, 2026
  21. Mikola Lysenko (mikolalysenko)
    removed
    agent:claimed
    on Oct 15, 2026
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

    agent:triagedbugSomething isn't workingSomething isn't workingbughuntFound by a scheduled package-manager bug-hunt agentFound by a scheduled package-manager bug-hunt agentpm:yarn-berryYarn Berry (2+)Yarn Berry (2+)priority:p2

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions

      You are visitor 01402503 — GeezerVison does not store the pages you look up.
      Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.