CVE-2026-55697: pnpm Repository-controlled ConfigDependencies Can Select A Vulnerability

HIGH
Advisory Identifier: GHSA-gj8w-mvpf-x27x
CVSS 7.5
CWE-829 CWE-78 CWE-494
Published
Advisory Summary

CVE-2026-55697 is a HIGH (CVSS 7.5) repository-controlled configdependencies can select a vulnerability (CWE-829: Inclusion of Functionality from Untrusted Control Sphere) affecting pnpm libraries in the npm ecosystem. The issue involves repository-controlled configdependencies can select a pacquet native install engine. Remediation is available by upgrading affected packages to version 10.34.2, 11.5.3.

CVE-2026-55697 at a Glance

CVE Identifier CVE-2026-55697
GHSA Identifier GHSA-gj8w-mvpf-x27x
Severity HIGH
CVSS v3.1 Base Score 7.5
CWE Classification CWE-829: Inclusion of Functionality from Untrusted Control Sphere
Affected Product pnpm
Package Ecosystem npm
Published Date
Last Updated

Security Impact

CVSS: 7.5

The security impact metrics below are parsed directly from the CVSS v3.1 vector string (CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:U/C:H/I:H/A:H).

Attack Vector Network (AV:N)
Attack Complexity High (AC:H)
Privileges Required None (PR:N)
User Interaction Required (UI:R)
Scope Unchanged (S:U)
Confidentiality High (C:H)
Integrity High (I:H)
Availability High (A:H)

How to Fix CVE-2026-55697

To remediate this vulnerability, upgrade all affected pnpm dependencies to a patched release. Both direct and transitive dependencies should be checked, as frameworks or security libraries may pull in vulnerable versions transitively.

pnpm fixed: 10.34.2
npm install pnpm@10.34.2
pnpm fixed: 11.5.3
npm install pnpm@11.5.3
Verify Direct and Transitive Dependencies

Run the following command in your project directory to verify that all resolved dependencies use the patched release:

npm ls pnpm

How to Check if You Are Affected

To determine whether your Node.js application is affected by CVE-2026-55697, inspect your project dependencies using npm:

npm ls pnpm

Analyze the terminal output to locate any version of pnpm in your dependency tree. If any resolved version matches the vulnerable ranges listed in the table below (for example, versions earlier than 10.34.2), your application is affected.

Note: The npm ls pnpm command inspects dependencies declared in your package.json and lockfile; it does not perform automated runtime dynamic scanning.

Technical Details

Vulnerability Mechanism & Technical Analysis

This vulnerability is classified under CWE-829: Inclusion of Functionality from Untrusted Control Sphere, where the product imports, requires, or includes executable functionality (such as a library) from a source that is outside of the intended control sphere. In pnpm, software state validation or input boundaries are circumvented during processing. Review the official source advisory statement below for specific affected components, classes, and reproduction details.

Source Advisory Statement

<!-- maintainer-action:start --> ## Maintainer Action Plan This report is ready to review with the shared patch branch. Start with the PR and the expected fixed behavior, then use the detailed exploit narrative below only if you want to replay the original path. - Advisory: `CAND-PNPM-097` / `GHSA-gj8w-mvpf-x27x` - Advisory URL: https://github.com/pnpm/pnpm/security/advisories/GHSA-gj8w-mvpf-x27x - Shared patch PR: https://github.com/pnpm/pnpm-ghsa-j2hc-m6cf-6jm8/pull/1 - Shared patch branch: `security/ghsa-batch-2026-06-09` - Patch commit: `a93449314f398cf4bdf2e28d033c02d37395ad22` - Base commit: `origin/main` `55a4035abf1ae3fe7208ba1f5ef43c5eff58ccec` - Maintainer priority: `start-here` - Component: `pnpm configDependencies / pacquet delegation` - Patch area: pacquet/configDependency lifecycle execution is not used as install engine without trust - Affected packages: `npm:pnpm`, `npm:@pnpm/config.reader`, `npm:@pnpm/installing.commands` - CWE IDs: `CWE-829`, `CWE-78`, `CWE-494` - Conservative CVSS: `7.5` / `CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:U/C:H/I:H/A:H` - Next action: review the shared patch branch for this component, set the final affected version range, merge and release the fix, then publish or close the advisory. ### Expected Patched Behavior config-dependency pacquet install engines are not selected unless the trusted allowlist is set outside the repository; the marker file is not created. ### Files And Tests To Review - `config/reader/src/Config.ts` - `config/reader/src/types.ts` - `config/reader/src/configFileKey.ts` - `config/reader/src/index.ts` - `config/reader/test/index.ts` - `installing/commands/src/installDeps.ts` - `installing/commands/test/runPacquet.ts` - `pnpm/test/install/pacquet.ts` - `.changeset/lucky-config-plugin-pnpmfiles.md` ### Focused Validation Run these from a checkout of the shared patch branch. They are the useful maintainer commands with machine-local artifact paths removed. ```bash ./node_modules/.bin/tsgo --build config/reader/tsconfig.json ./node_modules/.bin/tsgo --build installing/commands/tsconfig.json ./node_modules/.bin/tsgo --build pnpm/tsconfig.json NODE_OPTIONS="--experimental-vm-modules --disable-warning=ExperimentalWarning --disable-warning=DEP0169" ../../node_modules/.bin/jest test/runPacquet.ts --runInBand NODE_OPTIONS="--experimental-vm-modules --disable-warning=ExperimentalWarning --disable-warning=DEP0169" ../../node_modules/.bin/jest test/index.ts -t "config dependency code allowlists|user-level preference settings" --runInBand ./node_modules/.bin/eslint config/reader/src/Config.ts config/reader/src/types.ts config/reader/src/configFileKey.ts config/reader/src/index.ts config/reader/test/index.ts installing/commands/src/installDeps.ts installing/commands/test/runPacquet.ts pnpm/test/install/pacquet.ts git diff --check ``` The full patched replay for the shared branch passed with all 20 candidates marked fixed. This candidate's replay evidence is `results/CAND-PNPM-097-patched-result.json`. <!-- maintainer-action:end --> ### Summary pnpm can install `configDependencies` declared in `pnpm-workspace.yaml` before command dispatch. Before the patch, a repository could declare `pacquet` or `@pnpm/pacquet` as a config dependency and pnpm treated that repository-controlled dependency as an install-engine opt-in. During install, pnpm resolved a platform-specific `@pacquet/<platform>-<arch>/pacquet` binary from `node_modules/.pnpm-config/<packageName>` and spawned it as the developer or CI user. ### Details The vulnerable source-to-sink path was: - `config/reader/src/getOptionsFromRootManifest.ts` copies repository `pnpm-workspace.yaml` `configDependencies` into config. - `pnpm/src/getConfig.ts` installs config dependencies before command dispatch. - `installing/env-installer/src/resolveAndInstallConfigDeps.ts` resolves the repository-declared dependency and its optional platform subdependencies. - `installing/env-installer/src/installConfigDeps.ts` fetches, imports, and symlinks the config dependency tree under `node_modules/.pnpm-config`. - `installing/commands/src/installDeps.ts` selected pacquet delegation whenever `configDependencies` contained `pacquet` or `@pnpm/pacquet`. - `installing/deps-installer/src/install/index.ts` called `opts.runPacquet` from frozen and materialization paths. - `installing/commands/src/runPacquet.ts` resolved `@pacquet/${process.platform}-${process.arch}/pacquet` from the installed config dependency package and executed it with `spawn()`. Exact-version, integrity, and platform filters only proved which bytes package resolution selected; they did not establish that the repository was trusted to choose a native install engine. ### PoC Standalone PoC and verification script: Repository fixture: ```yaml packages: - . configDependencies: pacquet: 0.2.2 ``` Registry package shape: ```json { "name": "pacquet", "version": "0.2.2", "optionalDependencies": { "@pacquet/darwin-arm64": "0.2.2" } } ``` Platform package payload: ```sh #!/bin/sh echo "$PWD" > /tmp/pacquet-engine-ran env > /tmp/pacquet-engine-env ``` Pre-patch exploit model: 1. The victim runs a dependency-management command such as `pnpm install` in the repository. 2. pnpm installs the repository-declared config dependency and its host-compatible optional platform dependency into `.pnpm-config`. 3. `installDeps()` treats the presence of `configDependencies.pacquet` or `configDependencies["@pnpm/pacquet"]` as authorization to delegate install materialization. 4. `runPacquet()` resolves the platform binary from the installed config dependency tree and spawns it in the lockfile directory. Observed PoC output: ```json { "primitive": "repository-selected pacquet config dependency reaches native process execution when selected", "patchedWithoutAllowlist": "blocked", "trustedAllowlist": "allows explicit opt-in" } ``` Focused validation commands: ```bash ./node_modules/.bin/tsgo --build config/reader/tsconfig.json ./node_modules/.bin/tsgo --build installing/commands/tsconfig.json ./node_modules/.bin/tsgo --build pnpm/tsconfig.json NODE_OPTIONS="--experimental-vm-modules --disable-warning=ExperimentalWarning --disable-warning=DEP0169" ../../node_modules/.bin/jest test/runPacquet.ts --runInBand NODE_OPTIONS="--experimental-vm-modules --disable-warning=ExperimentalWarning --disable-warning=DEP0169" ../../node_modules/.bin/jest test/index.ts -t "config dependency code allowlists|user-level preference settings" --runInBand ./node_modules/.bin/eslint config/reader/src/Config.ts config/reader/src/types.ts config/reader/src/configFileKey.ts config/reader/src/index.ts config/reader/test/index.ts installing/commands/src/installDeps.ts installing/commands/test/runPacquet.ts pnpm/test/install/pacquet.ts git diff --check ``` Validation result: - The PoC confirmed a selected pacquet config dependency reaches native process execution. - Patched `getPacquetConfigDependencyName()` returns `undefined` without a trusted allowlist. - Patched `getPacquetConfigDependencyName()` allows exact `pacquet`, exact `@pnpm/pacquet`, and wildcard `*` trusted opt-in. - Config reader regressions prove user/global config can set `configDependencyInstallEngineAllowlist`, while `pnpm-workspace.yaml` cannot grant this permission to itself. - E2E fixtures that intentionally delegate to pacquet now pass the trusted allowlist through environment config. - TypeScript builds passed for `@pnpm/config.reader`, `@pnpm/installing.commands`, and `pnpm`. - Focused `installing/commands/test/runPacquet.ts`: 3 passed. - Focused `config/reader/test/index.ts`: 2 passed, 132 skipped under the focused pattern. - ESLint passed with warnings only for existing skipped tests in `config/reader/test/index.ts` and `pnpm/test/install/pacquet.ts`. - `git diff --check`: passed. ### Impact A malicious repository can cause pnpm to execute a registry-selected native binary while handling dependency-management commands. The binary runs with the victim developer or CI user's filesystem, environment, registry credentials, git/SSH credentials, and network access. ## Affected products Ecosystem: npm Package name: `pnpm`, `@pnpm/config.reader`, `@pnpm/installing.commands` Affected versions: current main before this patch, when `configDependencies` contains `pacquet` or `@pnpm/pacquet` and install paths delegate to pacquet. Patched versions: 10.34.2, 11.5.3. ## Severity Severity: High Vector string: `CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H` Base score: 8.8 Rationale: attacker input is delivered through a repository and registry package, exploitation is low complexity once the victim runs pnpm, no attacker privileges are required, and user interaction is required. Successful exploitation executes a native binary in the victim user's context, with high confidentiality, integrity, and availability impact. ## Weaknesses CWE-829: Inclusion of Functionality from Untrusted Control Sphere CWE-78: Improper Neutralization of Special Elements used in an OS Command CWE-494: Download of Code Without Integrity Check ## Patch The patch adds a trusted opt-in gate for config-dependency install-engine delegation: - New setting: `configDependencyInstallEngineAllowlist`. - The allowlist can be set from trusted user-controlled config such as global config, CLI config, or environment config. - `pnpm-workspace.yaml` cannot grant this permission to itself; workspace-provided values are discarded after workspace settings are merged. - `installDeps()` delegates to pacquet only when `pacquet`, `@pnpm/pacquet`, or `*` is present in the trusted allowlist. - Repositories can still install `pacquet` as a config dependency, but pnpm will not spawn it as an install engine unless trusted config opts in. - Existing tests that intentionally exercise pacquet delegation were updated to pass the trusted allowlist via environment config. Changed files: - `config/reader/src/Config.ts` - `config/reader/src/types.ts` - `config/reader/src/configFileKey.ts` - `config/reader/src/index.ts` - `config/reader/test/index.ts` - `installing/commands/src/installDeps.ts` - `installing/commands/test/runPacquet.ts` - `pnpm/test/install/pacquet.ts` Changeset: - `.changeset/lucky-config-plugin-pnpmfiles.md` Pacquet parity: No pacquet-side code-execution sink exists for this finding. The Rust port parses and records `configDependencies` for workspace-state compatibility, but it does not install config dependencies or select/spawn an alternate install engine from them. The user-visible trust setting is TypeScript-side today because it gates pnpm's pacquet delegation path. ## CVSS Reassessment Initial CVSS remains correct for vulnerable versions: `CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H` / 8.8 High. Final CVSS after patch: not vulnerable after patch / 0.0. The PoC no longer reaches pacquet install-engine selection or native process execution unless the victim has set a trusted allowlist outside the repository's own workspace settings. ## Remaining Risk Users can explicitly trust pacquet install-engine delegation through the new allowlist. That is intentional behavior; the closed issue is repository self-authorization of a registry-provided native install engine.

CVE-2026-55697 Affected pnpm Versions

2 component(s)
Fixed Versions:
10.34.211.5.3
Product / Package Ecosystem Affected Versions Fixed Version
pnpm
npm
< 10.34.2
10.34.2
pnpm
npm
≥ 11.0.0
< 11.5.3
11.5.3

References

Frequently Asked Questions

What is CVE-2026-55697?
CVE-2026-55697 is a security vulnerability in pnpm involving Repository-controlled configDependencies can select a pacquet native install engine under CWE-829: Inclusion of Functionality from Untrusted Control Sphere.
Which pnpm versions are affected?
Affected versions include releases prior to 10.34.2, 11.5.3 across affected packages: pnpm.
What version fixes CVE-2026-55697?
Upgrading to 10.34.2, 11.5.3 (or the latest patched release for your respective branch) resolves the vulnerability.
Is pnpm affected?
Yes, pnpm is affected in releases prior to 10.34.2, 11.5.3. Upgrade your dependency to 10.34.2, 11.5.3 or later.
What is the CVSS score of CVE-2026-55697?
CVE-2026-55697 has a CVSS v3.1 base score of 7.5 (HIGH) with vector string CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:U/C:H/I:H/A:H.
What CWE is associated with CVE-2026-55697?
CVE-2026-55697 is classified under CWE-829: Inclusion of Functionality from Untrusted Control Sphere (The product imports, requires, or includes executable functionality (such as a library) from a source that is outside of the intended control sphere.).
How can I check npm dependencies for CVE-2026-55697?
Run the dependency tree command: 'npm ls pnpm'. This command lists direct and transitive dependencies in your build configuration so you can verify if a vulnerable version is resolved.
Machine-readable OSV JSON OSV v1.5 Schema
Normalized schema output
{
  "schema_version" : "1.4.0",
  "id" : "GHSA-gj8w-mvpf-x27x",
  "modified" : "2026-08-13T16:06:30Z",
  "published" : "2026-06-26T23:20:47Z",
  "aliases" : [ "CVE-2026-55697" ],
  "summary" : "pnpm: Repository-controlled configDependencies can select a pacquet native install engine",
  "details" : "<!-- maintainer-action:start -->\n## Maintainer Action Plan\n\nThis report is ready to review with the shared patch branch. Start with the PR and the expected fixed behavior, then use the detailed exploit narrative below only if you want to replay the original path.\n\n- Advisory: `CAND-PNPM-097` / `GHSA-gj8w-mvpf-x27x`\n- Advisory URL: https://github.com/pnpm/pnpm/security/advisories/GHSA-gj8w-mvpf-x27x\n- Shared patch PR: https://github.com/pnpm/pnpm-ghsa-j2hc-m6cf-6jm8/pull/1\n- Shared patch branch: `security/ghsa-batch-2026-06-09`\n- Patch commit: `a93449314f398cf4bdf2e28d033c02d37395ad22`\n- Base commit: `origin/main` `55a4035abf1ae3fe7208ba1f5ef43c5eff58ccec`\n- Maintainer priority: `start-here`\n- Component: `pnpm configDependencies / pacquet delegation`\n- Patch area: pacquet/configDependency lifecycle execution is not used as install engine without trust\n- Affected packages: `npm:pnpm`, `npm:@pnpm/config.reader`, `npm:@pnpm/installing.commands`\n- CWE IDs: `CWE-829`, `CWE-78`, `CWE-494`\n- Conservative CVSS: `7.5` / `CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:U/C:H/I:H/A:H`\n- Next action: review the shared patch branch for this component, set the final affected version range, merge and release the fix, then publish or close the advisory.\n\n### Expected Patched Behavior\n\nconfig-dependency pacquet install engines are not selected unless the trusted allowlist is set outside the repository; the marker file is not created.\n\n### Files And Tests To Review\n\n- `config/reader/src/Config.ts`\n- `config/reader/src/types.ts`\n- `config/reader/src/configFileKey.ts`\n- `config/reader/src/index.ts`\n- `config/reader/test/index.ts`\n- `installing/commands/src/installDeps.ts`\n- `installing/commands/test/runPacquet.ts`\n- `pnpm/test/install/pacquet.ts`\n- `.changeset/lucky-config-plugin-pnpmfiles.md`\n\n### Focused Validation\n\nRun these from a checkout of the shared patch branch. They are the useful maintainer commands with machine-local artifact paths removed.\n\n```bash\n./node_modules/.bin/tsgo --build config/reader/tsconfig.json\n./node_modules/.bin/tsgo --build installing/commands/tsconfig.json\n./node_modules/.bin/tsgo --build pnpm/tsconfig.json\nNODE_OPTIONS=\"--experimental-vm-modules --disable-warning=ExperimentalWarning --disable-warning=DEP0169\" ../../node_modules/.bin/jest test/runPacquet.ts --runInBand\nNODE_OPTIONS=\"--experimental-vm-modules --disable-warning=ExperimentalWarning --disable-warning=DEP0169\" ../../node_modules/.bin/jest test/index.ts -t \"config dependency code allowlists|user-level preference settings\" --runInBand\n./node_modules/.bin/eslint config/reader/src/Config.ts config/reader/src/types.ts config/reader/src/configFileKey.ts config/reader/src/index.ts config/reader/test/index.ts installing/commands/src/installDeps.ts installing/commands/test/runPacquet.ts pnpm/test/install/pacquet.ts\ngit diff --check\n```\n\nThe full patched replay for the shared branch passed with all 20 candidates marked fixed. This candidate's replay evidence is `results/CAND-PNPM-097-patched-result.json`.\n<!-- maintainer-action:end -->\n\n### Summary\n\npnpm can install `configDependencies` declared in `pnpm-workspace.yaml` before command dispatch. Before the patch, a repository could declare `pacquet` or `@pnpm/pacquet` as a config dependency and pnpm treated that repository-controlled dependency as an install-engine opt-in. During install, pnpm resolved a platform-specific `@pacquet/<platform>-<arch>/pacquet` binary from `node_modules/.pnpm-config/<packageName>` and spawned it as the developer or CI user.\n\n### Details\n\nThe vulnerable source-to-sink path was:\n\n- `config/reader/src/getOptionsFromRootManifest.ts` copies repository `pnpm-workspace.yaml` `configDependencies` into config.\n- `pnpm/src/getConfig.ts` installs config dependencies before command dispatch.\n- `installing/env-installer/src/resolveAndInstallConfigDeps.ts` resolves the repository-declared dependency and its optional platform subdependencies.\n- `installing/env-installer/src/installConfigDeps.ts` fetches, imports, and symlinks the config dependency tree under `node_modules/.pnpm-config`.\n- `installing/commands/src/installDeps.ts` selected pacquet delegation whenever `configDependencies` contained `pacquet` or `@pnpm/pacquet`.\n- `installing/deps-installer/src/install/index.ts` called `opts.runPacquet` from frozen and materialization paths.\n- `installing/commands/src/runPacquet.ts` resolved `@pacquet/${process.platform}-${process.arch}/pacquet` from the installed config dependency package and executed it with `spawn()`.\n\nExact-version, integrity, and platform filters only proved which bytes package resolution selected; they did not establish that the repository was trusted to choose a native install engine.\n\n### PoC\n\nStandalone PoC and verification script:\n\nRepository fixture:\n\n```yaml\npackages:\n  - .\nconfigDependencies:\n  pacquet: 0.2.2\n```\n\nRegistry package shape:\n\n```json\n{\n  \"name\": \"pacquet\",\n  \"version\": \"0.2.2\",\n  \"optionalDependencies\": {\n    \"@pacquet/darwin-arm64\": \"0.2.2\"\n  }\n}\n```\n\nPlatform package payload:\n\n```sh\n#!/bin/sh\necho \"$PWD\" > /tmp/pacquet-engine-ran\nenv > /tmp/pacquet-engine-env\n```\n\nPre-patch exploit model:\n\n1. The victim runs a dependency-management command such as `pnpm install` in the repository.\n2. pnpm installs the repository-declared config dependency and its host-compatible optional platform dependency into `.pnpm-config`.\n3. `installDeps()` treats the presence of `configDependencies.pacquet` or `configDependencies[\"@pnpm/pacquet\"]` as authorization to delegate install materialization.\n4. `runPacquet()` resolves the platform binary from the installed config dependency tree and spawns it in the lockfile directory.\n\nObserved PoC output:\n\n```json\n{\n  \"primitive\": \"repository-selected pacquet config dependency reaches native process execution when selected\",\n  \"patchedWithoutAllowlist\": \"blocked\",\n  \"trustedAllowlist\": \"allows explicit opt-in\"\n}\n```\n\nFocused validation commands:\n\n```bash\n./node_modules/.bin/tsgo --build config/reader/tsconfig.json\n./node_modules/.bin/tsgo --build installing/commands/tsconfig.json\n./node_modules/.bin/tsgo --build pnpm/tsconfig.json\nNODE_OPTIONS=\"--experimental-vm-modules --disable-warning=ExperimentalWarning --disable-warning=DEP0169\" ../../node_modules/.bin/jest test/runPacquet.ts --runInBand\nNODE_OPTIONS=\"--experimental-vm-modules --disable-warning=ExperimentalWarning --disable-warning=DEP0169\" ../../node_modules/.bin/jest test/index.ts -t \"config dependency code allowlists|user-level preference settings\" --runInBand\n./node_modules/.bin/eslint config/reader/src/Config.ts config/reader/src/types.ts config/reader/src/configFileKey.ts config/reader/src/index.ts config/reader/test/index.ts installing/commands/src/installDeps.ts installing/commands/test/runPacquet.ts pnpm/test/install/pacquet.ts\ngit diff --check\n```\n\nValidation result:\n\n- The PoC confirmed a selected pacquet config dependency reaches native process execution.\n- Patched `getPacquetConfigDependencyName()` returns `undefined` without a trusted allowlist.\n- Patched `getPacquetConfigDependencyName()` allows exact `pacquet`, exact `@pnpm/pacquet`, and wildcard `*` trusted opt-in.\n- Config reader regressions prove user/global config can set `configDependencyInstallEngineAllowlist`, while `pnpm-workspace.yaml` cannot grant this permission to itself.\n- E2E fixtures that intentionally delegate to pacquet now pass the trusted allowlist through environment config.\n- TypeScript builds passed for `@pnpm/config.reader`, `@pnpm/installing.commands`, and `pnpm`.\n- Focused `installing/commands/test/runPacquet.ts`: 3 passed.\n- Focused `config/reader/test/index.ts`: 2 passed, 132 skipped under the focused pattern.\n- ESLint passed with warnings only for existing skipped tests in `config/reader/test/index.ts` and `pnpm/test/install/pacquet.ts`.\n- `git diff --check`: passed.\n\n### Impact\n\nA malicious repository can cause pnpm to execute a registry-selected native binary while handling dependency-management commands. The binary runs with the victim developer or CI user's filesystem, environment, registry credentials, git/SSH credentials, and network access.\n\n## Affected products\n\nEcosystem: npm\n\nPackage name: `pnpm`, `@pnpm/config.reader`, `@pnpm/installing.commands`\n\nAffected versions: current main before this patch, when `configDependencies` contains `pacquet` or `@pnpm/pacquet` and install paths delegate to pacquet.\n\nPatched versions: 10.34.2, 11.5.3.\n\n## Severity\n\nSeverity: High\n\nVector string: `CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H`\n\nBase score: 8.8\n\nRationale: attacker input is delivered through a repository and registry package, exploitation is low complexity once the victim runs pnpm, no attacker privileges are required, and user interaction is required. Successful exploitation executes a native binary in the victim user's context, with high confidentiality, integrity, and availability impact.\n\n## Weaknesses\n\nCWE-829: Inclusion of Functionality from Untrusted Control Sphere\n\nCWE-78: Improper Neutralization of Special Elements used in an OS Command\n\nCWE-494: Download of Code Without Integrity Check\n\n## Patch\n\nThe patch adds a trusted opt-in gate for config-dependency install-engine delegation:\n\n- New setting: `configDependencyInstallEngineAllowlist`.\n- The allowlist can be set from trusted user-controlled config such as global config, CLI config, or environment config.\n- `pnpm-workspace.yaml` cannot grant this permission to itself; workspace-provided values are discarded after workspace settings are merged.\n- `installDeps()` delegates to pacquet only when `pacquet`, `@pnpm/pacquet`, or `*` is present in the trusted allowlist.\n- Repositories can still install `pacquet` as a config dependency, but pnpm will not spawn it as an install engine unless trusted config opts in.\n- Existing tests that intentionally exercise pacquet delegation were updated to pass the trusted allowlist via environment config.\n\nChanged files:\n\n- `config/reader/src/Config.ts`\n- `config/reader/src/types.ts`\n- `config/reader/src/configFileKey.ts`\n- `config/reader/src/index.ts`\n- `config/reader/test/index.ts`\n- `installing/commands/src/installDeps.ts`\n- `installing/commands/test/runPacquet.ts`\n- `pnpm/test/install/pacquet.ts`\n\nChangeset:\n\n- `.changeset/lucky-config-plugin-pnpmfiles.md`\n\nPacquet parity:\n\nNo pacquet-side code-execution sink exists for this finding. The Rust port parses and records `configDependencies` for workspace-state compatibility, but it does not install config dependencies or select/spawn an alternate install engine from them. The user-visible trust setting is TypeScript-side today because it gates pnpm's pacquet delegation path.\n\n## CVSS Reassessment\n\nInitial CVSS remains correct for vulnerable versions: `CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H` / 8.8 High.\n\nFinal CVSS after patch: not vulnerable after patch / 0.0. The PoC no longer reaches pacquet install-engine selection or native process execution unless the victim has set a trusted allowlist outside the repository's own workspace settings.\n\n## Remaining Risk\n\nUsers can explicitly trust pacquet install-engine delegation through the new allowlist. That is intentional behavior; the closed issue is repository self-authorization of a registry-provided native install engine.",
  "severity" : [ {
    "type" : "CVSS_V3",
    "score" : "CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:U/C:H/I:H/A:H"
  } ],
  "affected" : [ {
    "package" : {
      "ecosystem" : "npm",
      "name" : "pnpm"
    },
    "ranges" : [ {
      "type" : "ECOSYSTEM",
      "events" : [ {
        "introduced" : "0"
      }, {
        "fixed" : "10.34.2"
      } ]
    } ]
  }, {
    "package" : {
      "ecosystem" : "npm",
      "name" : "pnpm"
    },
    "ranges" : [ {
      "type" : "ECOSYSTEM",
      "events" : [ {
        "introduced" : "11.0.0"
      }, {
        "fixed" : "11.5.3"
      } ]
    } ]
  } ],
  "references" : [ {
    "type" : "WEB",
    "url" : "https://github.com/pnpm/pnpm/security/advisories/GHSA-gj8w-mvpf-x27x"
  }, {
    "type" : "ADVISORY",
    "url" : "https://nvd.nist.gov/vuln/detail/CVE-2026-55697"
  }, {
    "type" : "PACKAGE",
    "url" : "https://github.com/pnpm/pnpm"
  } ],
  "database_specific" : {
    "cwe_ids" : [ "CWE-494", "CWE-78", "CWE-829" ],
    "severity" : "HIGH",
    "github_reviewed" : true,
    "github_reviewed_at" : "2026-06-26T23:20:47Z",
    "nvd_published_at" : "2026-06-25T18:16:40Z"
  }
}