Listen to this Post
This vulnerability, tracked as CAND-PNPM-123 and GHSA-5wx6-mg75-v57r, details a security bypass in pnpm’s build approval mechanism for opaque dependencies. The initial upstream commit (bf1b731ee6) fixed a name-only approval bypass by making the build policy consume the resolved dependency identity. However, a collision remained: the generic peer-suffix normalizer stripped parenthesized text from all non-registry locators, including git, URL, tarball, and file sources. This meant an approval for one source string could authorize a different, attacker-controlled source that normalized to the same value.
The security boundary clarified that registry identities still normalize peer suffixes, but opaque identities must now match the complete resolved locator byte-for-byte. Explicit denials use the same normalization as approvals, and ignored-build output preserves the exact opaque identity so the key a user approves is the exact key policy later checks. Both TypeScript pnpm and pacquet implement the same distinction.
The exploit replay demonstrates three collision forms. First, with `allowBuilds` approving foo@https://host/pkg.tgz`, the upstream implementation also acceptedfoo@https://host/pkg.tgz(evil)` because both passed through peer-suffix removal. Second, a Rust-only form showed foo@https://host/[email protected](good)` andfoo@https://host/[email protected](evil)` collided because the parser selected the final `@` and misclassified the opaque URL as a registry package. Third, the same parser hazard appeared in source-only locators ending in a semver-looking tail: approval for https://host/[email protected]` could collapsehttps://host/[email protected](evil)`.
The final patch rejects all three collision forms, applies the same exactness to deny rules, accepts exact opaque keys as positive controls, and continues to accept registry packages approved without their peer suffixes. Files changed include `building/policy/src/index.ts` and `building/policy/test/index.ts` which normalize only parsed registry identities and retain exact opaque keys. `pacquet/crates/package-manager/src/build_modules.rs` passes snapshot identities to policy and preserves opaque locators. `pacquet/crates/package-manager/src/build_modules/tests.rs` covers exact approval and denial, all three collision forms, ignored-build output, and registry peer compatibility. `.changeset/quiet-opaque-build-identities.md` records patch releases for `@pnpm/building.policy` and pnpm.
Validation included the TypeScript policy suite passing all 16 tests and the final pacquet build-policy suite passing all 49 tests. The new Rust regression reproduced the extra-@ collision before the additive fix and passed afterward. Exact opaque approval and denial, source-only semver-tail collision rejection, registry peer normalization, and ignored-build reporting all have paired tests. ESLint, Rust formatting, and diff checks passed. The branch consists of three focused security commits.
Patches were released in versions 10.34.2 and 11.5.3. Registry package approvals keep their existing form, but opaque dependencies that were approved through a normalized parenthesized variant must now use the exact key shown in pnpm’s ignored-build output.
DailyCVE Form
Platform: `pnpm`
Version: `10.34.2, 11.5.3`
Vulnerability: `Build approval bypass`
Severity: `High`
date: `2026-06-26`
Prediction: `Already Patched`
What Undercode Say
Analytics:
$ jest building/policy/test/index.ts --runInBand 16 passed $ cargo test -p pacquet-package-manager build_modules::tests -- --nocapture 49 passed $ cargo fmt --all -- --check PASS $ git diff --check 84bb4b1a046f3a659de1c9aab1d45dcf814124ce...HEAD PASS
Exploit
The vulnerability could be exploited in three specific ways:
1. Parenthesized Suffix Collision: With `allowBuilds` approving foo@https://host/pkg.tgz`, the vulnerable implementation also acceptedfoo@https://host/pkg.tgz(evil)` because both passed through peer-suffix removal.
2. Rust Parser Collision: foo@https://host/[email protected](good)` andfoo@https://host/[email protected](evil)` collided because the parser selected the final `@` and misclassified the opaque URL as a registry package.
3. Semver Tail Collision: Approval for https://host/[email protected]` could collapsehttps://host/[email protected](evil)`.
Protection
- Upgrade to pnpm version 10.34.2 or 11.5.3.
- The final patch rejects all three collision forms and applies exactness to deny rules.
- Opaque dependencies must now use the exact key shown in pnpm’s ignored-build output.
Impact
- An attacker could authorize a different, attacker-controlled source whose locator normalized to the same value as an approved source.
- This bypasses the build approval mechanism for opaque dependencies.
- The fix ensures Git, URL, tarball, file, directory, and otherwise opaque identities must match the complete resolved locator byte for byte.
🎯Let’s Practice Exploiting & Learn Patching For Free:
🎓 Live Courses & Certifications:
Join Undercode Academy for Verified Certifications
🚀 Request a Custom Project:
Secure, high-velocity infrastructure and disruptive technological engineering. Contact our engineering team for high-tier development and proprietary systems:
[email protected]
💎 Smart Architecture | 🛡️ Secure by Design | ⭐ Trusted by Thousands
Sources:
Reported By: github.com
Extra Source Hub:
Undercode

