---
title: "pnpm 11.7 bringt `frozenStore` für Read-Only-Dateisysteme, lässt pacquet Abhängigkeiten auflösen und schließt einen Lockfile-Path-Traversal"
description: "pnpm 11.7.0 (15. Juni 2026) liefert vier Kernänderungen: einen `--frozen-store`-Install-Modus für Nix-Stores, OCI-Layer und andere Read-Only-Mounts; die Delegation der Abhängigkeitsauflösung an den pacquet-Rust-Port (nicht nur die Materialisierung); ein optionales `--batch`-Flag für `pnpm publish --recursive`; und einen Security-Fix, der Path-Traversal- und reservierte Aliasse (`.bin`, `.pnpm`, `node_modules`, `../../escape`) aus dem Lockfile zurückweist."
date: 2026-06-17
image: "/images/heroes/2026-06-17--pnpm-11-7-frozen-store-publish-batch.png"
author: lschvn
tags: ["security", "tooling", "performance"]
tldr:
  - "pnpm 11.7.0 erschien am 15. Juni 2026 mit einem neuen `--frozen-store`-Install-Modus, der die `index.db` des Package-Stores mit der SQLite-URI `immutable=1` öffnet und jeden Store-Schreibpfad unterdrückt, sodass `pnpm install` gegen ein Read-Only-Dateisystem (Nix-Store, OCI-Layer, Read-Only-Bind-Mount) laufen kann. Kombiniert mit `--offline --frozen-lockfile` für vollständig reproduzierbare Installs. Erfordert Node.js 22.15+, 23.11+ oder 24+."
  - "Der pacquet-Rust-Port von pnpm übernimmt nun die Abhängigkeitsauflösung End-to-End (nicht nur die Materialisierung) bei einem Non-Frozen-Install, sofern die installierte pacquet-Version mindestens 0.11.7 ist. Ältere pacquet-Releases behalten die Trennung Resolve-dann-Materialize, und `add`/`update`/`remove` lösen weiterhin in pnpm auf (sie müssen zuerst die Manifeste mutieren)."
  - "Das Release schließt zudem eine echte Lockfile-Angriffsfläche: Ein präparierter Lockfile-Alias konnte direkt unter einem gehoisteten `node_modules`-Verzeichnis eingehängt werden, sodass Package-Dateien außerhalb des Install-Roots geschrieben oder das pnpm-Layout überschrieben werden konnte. Der Fix fügt zwei Validierungsschichten hinzu (im `hoisted`-Graph-Builder und im Lockfile-Verifikations-Gate), die reservierte Aliasse wie `.bin`, `.pnpm`, `node_modules` und jedes Path-Traversal-Muster ablehnen, unabhängig vom Node-Linker."
faq:
  - question: "Was ist neu in pnpm 11.7?"
    answer: "pnpm 11.7.0 (15. Juni 2026) liefert einen `--frozen-store`-Install-Modus für Read-Only-Dateisysteme (Nix-Stores, OCI-Layer, Read-Only-Mounts), lässt den pacquet-Rust-Port die Abhängigkeitsauflösung End-to-End bei einem Non-Frozen-Install übernehmen, fügt ein optionales `--batch`-Flag für `pnpm publish --recursive` hinzu und schließt eine Lockfile-Path-Traversal-Schwachstelle. Außerdem behebt das Release eine Windows-Regression in `pnpm add`, einen Path-Scoping-Bug in `pnpm patch-remove` und einen deterministischen Kind-Auflösungs-Edge-Case bei geteilten Packages."
  - question: "Was ist `frozenStore` und wann brauche ich es?"
    answer: "`frozenStore` (Config-Key, auch als `--frozen-store` auf der CLI verfügbar) ist ein neuer Install-Modus für Read-Only-Dateisysteme. Die `index.db` des Stores wird mit der [`immutable=1`-URI](https://www.sqlite.org/uri.html) geöffnet, was die WAL/`-shm`-Sidecar-Erstellung umgeht, die auf einem Read-Only-Verzeichnis sonst mit `EROFS` scheitern würde. pnpm unterdrückt zudem jeden Store-Schreibpfad: den `index.db`-Writer, den Projekt-Registry-Write, den Side-Effects-Cache und das `chmod`, das eine Bin-Datei ausführbar macht. Ziel ist ein vollständig reproduzierbarer Install, bei dem der Store als vorberechnetes Artefakt ausgeliefert wird (Nix-Store, OCI-Image-Layer, Read-Only-Mount) und während des Installs nicht mutiert werden darf."
  - question: "Was ist die Node.js-Voraussetzung für `--frozen-store`?"
    answer: "Die `immutable=1`-URI benötigt Node.js 22.15.0, 23.11.0 oder 24.0.0 oder neuer. Auf älteren Runtimes schlägt `--frozen-store` schnell mit `ERR_PNPM_FROZEN_STORE_UNSUPPORTED_NODE` fehl, statt den Store stillschweigend in einer Weise zu öffnen, die die WAL mutiert. Die anderen `--frozen-*`-Flags (--offline, --frozen-lockfile) funktionieren wie bei einem normalen Install."
  - question: "Wie funktioniert die pacquet-Auflösungs-Delegation?"
    answer: "Wenn pacquet in `configDependencies` deklariert ist und die installierte Version mindestens 0.11.7 ist, delegiert ein normaler Non-Frozen-Install (isolierter `nodeLinker`, einfaches `pnpm install`) sowohl Auflösung als auch Materialisierung in einem Durchgang an pacquet: pacquet liest die Manifeste, schreibt `pnpm-lock.yaml` und erzeugt `node_modules`. Das Lockfile-Format bleibt gleich. Ältere pacquet-Versionen übernehmen nur die Materialisierung, und `pnpm add`, `pnpm update` und `pnpm remove` lösen weiterhin in pnpm auf (sie müssen zuerst die Manifeste mutieren, danach materialisiert pacquet). Die Erkennung erfolgt automatisch anhand der installierten pacquet-Version."
  - question: "Was war die Lockfile-Path-Traversal-Schwachstelle?"
    answer: "Vor 11.7 konnte ein Angreifer, der einen Lockfile-Eintrag kontrollieren konnte (ein bösartiges Postinstall, ein manipuliertes CI-Artefakt, ein vergifteter Resolved-Spec einer Peer-Dependency) einen Abhängigkeits-Alias auf einen Path-Traversal-String (`../../../escape`) oder einen reservierten Namen (`.bin`, `.pnpm`, `node_modules`) setzen. Unter `nodeLinker: hoisted` wurde der Alias direkt unter `node_modules` eingehängt, sodass Package-Dateien außerhalb des Install-Roots geschrieben oder das pnpm-Layout überschrieben werden konnte. Die Exploit-Klasse ist dieselbe, die der [Windows-Path-Traversal in esbuild 0.28.1 (GHSA-g7r4-m6w7-qqqr)](/articles/2026-06-14-esbuild-0-28-1-deno-rce-windows-path-traversal) und der [Axios-npm-Supply-Chain-Angriff vom März 2026](/articles/2026-03-31-axios-npm-supply-chain-attack) jeweils in einem anderen Tool offengelegt haben."
  - question: "Funktioniert pnpm 11.7 mit meinem bestehenden Lockfile?"
    answer: "Ja. Das Lockfile-Format ist in 11.7 unverändert. Das neue Lockfile-Verifikations-Gate läuft bei jedem Install gegen das bestehende Lockfile und weist jeden Eintrag zurück, der die Alias-Prüfung nicht besteht, aber das Format selbst ändert sich nicht. Der einzige praktische Effekt für ein bestehendes Projekt ist, dass ein Eintrag mit einem Path-Traversal- oder reservierten Alias (was ein zuvor präparierter Angriff wäre, kein normaler Eintrag) den Install nun mit einem klaren Fehler abbricht, statt stillschweigend angewendet zu werden."
  - question: "Was macht das neue `--batch`-Flag für `pnpm publish --recursive`?"
    answer: "Das `--batch`-Flag ist optional und sendet alle ausgewählten Pakete in einer einzigen `PUT /-/pnpm/v1/publish`-Anfrage an die Registry, statt einer Anfrage pro Paket. Die Ziel-Registry muss den Batch-Publish-Endpoint implementieren (pnpr tut das); Registries, die das nicht tun, werden mit einem klaren `ERR_PNPM_BATCH_PUBLISH_UNSUPPORTED`-Fehler gemeldet. Der Batch wird von pnpr All-or-Nothing verarbeitet: Scheitert die Validierung eines Pakets im Batch, wird keines der Pakete veröffentlicht."
  - question: "Ist pnpm 11.7 ein Breaking Change für normale Projekte?"
    answer: "Nein. Das Lockfile-Format ist unverändert, die neue Alias-Validierung läuft gegen bestehende Lockfiles (und weist nur Einträge zurück, die nie hätten da sein sollen), `frozenStore` ist opt-in, die pacquet-Auflösungs-Delegation ist opt-in (greift nur, wenn pacquet in `configDependencies` deklariert ist), und das `--batch`-Flag ist opt-in. Die einzige Breaking Change in 11.7 ist ein Fix für die Windows-Regression in `pnpm add`, die in 11.6.0 eingeführt wurde (`Cannot destructure property 'manifest'`) und in 11.7 bereits behoben ist."
---

[pnpm 11.7.0](https://github.com/pnpm/pnpm/releases/tag/v11.7.0) erschien am 15. Juni 2026, vier Tage nach [dem 11.6.0-Security-Release, der die `.npmrc`-Umgebungsvariablen-Expansions-Schwachstelle (GHSA-3qhv-2rgh-x77r) behoben hat](https://github.com/pnpm/pnpm/security/advisories/GHSA-3qhv-2rgh-x77r). Die 11.7-Linie setzt die 11.6-Geschichte zur Härtung der Supply Chain fort und ergänzt drei Features, die verändern, wie Teams pnpm in containerisierten und reproduzierbaren Build-Umgebungen betreiben: einen `--frozen-store`-Install-Modus für Read-Only-Dateisysteme, die vollständige Delegation der Abhängigkeitsauflösung an den pacquet-Rust-Port und einen optionalen Batch-Modus für `pnpm publish --recursive`. Dazu kommt ein echter Lockfile-Security-Fix, der einen Path-Traversal-Edge-Case schließt, den [die Retrospektive zum npm-Supply-Chain-Angriff im Juni 2026](/articles/2026-06-06-npm-supply-chain-attack-red-hat-mini-shai-hulud) als wiederkehrende Bug-Klasse im gesamten Ökosystem markiert hat.

## `frozenStore`: Installs gegen einen Read-Only-Package-Store

Das Top-Feature von 11.7 ist `frozenStore` (Config-Key) und `--frozen-store` (CLI-Flag), ein Install-Modus für Umgebungen, in denen der Package-Store auf einem Read-Only-Dateisystem liegt: einem Nix-Store, einem OCI-Image-Layer, einem Read-Only-Bind-Mount oder einem `dm-verity`-Rootfs. Die `index.db` des Stores wird mit der [`immutable=1`-URI](https://www.sqlite.org/uri.html) geöffnet, was die WAL/`-shm`-Sidecar-Erstellung umgeht, die auf einem Read-Only-Verzeichnis sonst mit `EROFS` scheitern würde. Jeder Store-Schreibpfad wird unterdrückt: der `index.db`-Writer, der Projekt-Registry-Write, der Side-Effects-Cache und das `chmod`, das eine Bin-Datei normalerweise ausführbar macht, wenn sie eine Read/Write-Grenze überschreitet.

Die vorgesehene Kombination ist `--offline --frozen-lockfile --frozen-store` gegen einen vollständig befüllten Store. Unter dem Global Virtual Store (Standard seit 9.x) leben die Package-Verzeichnisse innerhalb des Stores. Fehlt im Store das Build-Output eines Pakets, dessen Lifecycle-Skripte genehmigt sind (oder das einen pnpm-Patch hat), schlägt pnpm früh mit `ERR_PNPM_FROZEN_STORE_NEEDS_BUILD` fehl, statt mitten im Build auf einem Read-Only-Write abzustürzen. Fehlt dem Store sein Content-Verzeichnis vollständig, schlägt der Install schnell mit `ERR_PNPM_FROZEN_STORE_INCOMPLETE` fehl, statt zu versuchen, ihn zu initialisieren.

Zwei harte Einschränkungen sind zu beachten. Die `immutable=1`-URI benötigt Node.js 22.15.0, 23.11.0 oder 24.0.0 oder neuer; auf älteren Runtimes schlägt `--frozen-store` mit dem klaren Fehler `ERR_PNPM_FROZEN_STORE_UNSUPPORTED_NODE` fehl. Und `--frozen-store` ist inkompatibel mit `--force` und mit einem konfigurierten pnpr-Server, da beide in den Store schreiben. Bin-Linking toleriert ebenfalls einen Read-Only-Store: Unter dem Global Virtual Store lebt die Bin-Quelle eines Pakets innerhalb des Stores, also würde das `chmod`, das sie ausführbar macht, abgelehnt. Bei `EPERM`/`EACCES` oder bei `EROFS` auf einem wirklich Read-Only-Dateisystem überspringt pnpm das `chmod` nun, wenn die Bin-Quelle bereits ausführbar ist und einen normalisierten Shebang hat, und wirft andernfalls weiterhin einen Fehler. Das `chmod` ist redundant, wenn der Seed seine Bin-Dateien bereits ausführbar ausliefert.

Das Ergebnis ist ein vollständig reproduzierbarer Install, der als einzelnes Artefakt zwischengespeichert und über CI, lokale Entwicklung und Produktion hinweg wiederverwendet werden kann, ohne Schreibzugriff auf den Store. Für Nix- und OCI-Nutzer ist dies das fehlende Puzzleteil: pnpm 11.6 war in diesen Umgebungen bereits nutzbar, aber jeder Install versuchte ein WAL-`chmod` oder einen `shm`-Sidecar-Write, der entweder fehlschlug oder auf einen langsameren Code-Pfad zurückfiel. 11.7 macht den Read-Only-Fall zum expliziten, unterstützten Modus.

## pacquet löst nun Abhängigkeiten auf, nicht nur die Materialisierung

Das zweite Feature ist ein Meilenstein für den [pacquet-Rust-Port von pnpm](https://github.com/pnpm/pnpm/tree/main/pacquet): Die Abhängigkeitsauflösung reiht sich in die Menge der Operationen ein, die pacquet End-to-End ausführen kann. Das neue Verhalten ist über `configDependencies` opt-in: Wenn pacquet in `configDependencies` deklariert ist und die installierte Version mindestens 0.11.7 ist, wird ein normaler Non-Frozen-Install (isolierter `nodeLinker`, einfaches `pnpm install`) in einem Durchgang an pacquet delegiert. pacquet liest die Manifeste, schreibt `pnpm-lock.yaml` und erstellt `node_modules`. pnpm erkennt die Fähigkeit anhand der installierten pacquet-Version; ältere Releases behalten die Trennung Auflösung-dann-Materialisierung.

`pnpm add`, `pnpm update` und `pnpm remove` lösen weiterhin in pnpm selbst auf, da diese Befehle die Manifeste mutieren müssen, bevor eine Auflösung stattfinden kann. Nach der Manifest-Mutation materialisiert pacquet. Das Lockfile-Format ändert sich nicht. Es bleibt eine optionale Vorschau der Rust-Install-Engine, verfolgt unter [#11723](https://github.com/pnpm/pnpm/issues/11723). Für Projekte, die pacquet bereits im Frozen-Install-Modus betreiben, ist die Änderung unsichtbar: Auflösung und Materialisierung sind bereits ein einziger pacquet-Aufruf. Für Projekte, die noch auf der Node.js-Install-Engine laufen, ist das Upgrade ein No-Op, solange pacquet nicht in `configDependencies` steht.

## Ablehnung von Path-Traversal- und reservierten Aliassen aus dem Lockfile

Der dritte Kernpunkt ist ein Security-Fix im Lockfile-Verifizierer. Vor 11.7 konnte ein Angreifer, der einen Lockfile-Eintrag kontrollieren konnte (ein bösartiges Postinstall, ein manipuliertes CI-Artefakt, ein vergifteter Resolved-Spec einer Peer-Dependency) einen Abhängigkeits-Alias auf einen Path-Traversal-String (`../../../escape`) oder einen reservierten Namen (`.bin`, `.pnpm`, `node_modules`) setzen. Unter `nodeLinker: hoisted` wurde der Alias direkt unter `node_modules` eingehängt, sodass Package-Dateien außerhalb des Install-Roots geschrieben oder das pnpm-Layout überschrieben werden konnte. Die Exploit-Klasse ist dieselbe, die der [Windows-Path-Traversal in esbuild 0.28.1 (GHSA-g7r4-m6w7-qqqr)](/articles/2026-06-14-esbuild-0-28-1-deno-rce-windows-path-traversal) und der [Axios-npm-Supply-Chain-Angriff vom März 2026](/articles/2026-03-31-axios-npm-supply-chain-attack) jeweils in einem anderen Tool offengelegt haben.

Der 11.7-Fix fügt zwei Schichten hinzu. Der `hoisted`-Graph-Builder validiert nun jeden Alias am Verzeichnis-Sink (`safeJoinModulesDir`), was der Validierung entspricht, die pnpm bereits für aus Manifesten stammende Aliasse durchgeführt hat. Und das Lockfile-Verifikations-Gate (`verifyLockfileResolutions`) führt eine immer aktive, policy-unabhängige Prüfung aus, die jeden Importer- oder Snapshot-Abhängigkeits-Alias zurückweist, der kein gültiger Package-Name ist, und den Install früh abbricht, vor jedem Fetch oder Dateisystem-Zugriff, für jeden Node-Linker gleichzeitig. Die Prüfung ist konservativ: Jeder Alias, der syntaktisch kein gültiger Package-Name ist (kein `/`, kein `..`, keine reservierten Segmente), wird mit einem klaren Fehler abgelehnt.

Für ein normales Projekt ist der praktische Effekt, dass ein bestehendes Lockfile weiterhin wie zuvor installiert wird, und ein Lockfile mit einem Path-Traversal- oder reservierten Alias (was ein zuvor präparierter Angriff wäre, kein normaler Eintrag) den Install nun mit einem klaren Fehler abbricht. Der Fix ändert das Lockfile-Format nicht. Es ist die Art von Defense-in-Depth, die bereits der `.npmrc`-Advisory in 11.6.0 verkörperte: Ein Projekt, das seiner Lockfile-Quelle bereits vertraut, profitiert dennoch vom Verifizierer, da dieser vor Bugs im Lockfile-Generator und vor teilweiser Korruption schützt.

## `--batch` für `pnpm publish --recursive`

Das vierte Feature ist klein, aber praktisch: `pnpm publish --recursive --batch` sendet alle ausgewählten Pakete in einer einzigen `PUT /-/pnpm/v1/publish`-Anfrage an die Registry, statt einer Anfrage pro Paket. Die Ziel-Registry muss den Batch-Publish-Endpoint implementieren (pnpr tut das); Registries, die das nicht tun, werden mit einem klaren `ERR_PNPM_BATCH_PUBLISH_UNSUPPORTED`-Fehler gemeldet. Der Batch wird von pnpr All-or-Nothing verarbeitet: Scheitert die Validierung eines Pakets im Batch, wird keines der Pakete veröffentlicht. Für Monorepos, die N Pakete pro Release veröffentlichen, ist der Wand-Zeit-Gewinn bei `pnpm publish --recursive` ungefähr Nx.

## Weitere Fixes für den Arbeitsalltag

Das 11.7-Release behebt zudem mehrere Korrektheits- und Regressions-Bugs, die seit 11.6 offen waren. Am auffälligsten ist eine Windows-Regression in `pnpm add`, die `Cannot destructure property 'manifest' of 'manifestsByPath[rootDir]' as it is undefined` erzeugte, wenn man außerhalb eines Workspaces lief; die Ursache war, dass `selectProjectByDir` den `ProjectsGraph` nach `opts.dir` statt nach `project.rootDir` schlüsselte, sodass nachgelagerte `manifestsByPath`-Lookups fehlschlugen, wenn sich die beiden Pfade unterschiedlich normalisierten (typischerweise die Groß-/Kleinschreibung des Laufwerksbuchstabens). Der Befehl `pnpm patch-remove` entfernt keine Dateien mehr außerhalb des konfigurierten Patches-Verzeichnisses. `pnpm publish` respektiert nun `strictSsl: false` für selbstsignierte Zertifikate auf die gleiche Weise wie `pnpm install`. Git-Dependencies, die auf ein Unterverzeichnis eines Repositorys zeigen (`repo#commit&path:/sub/dir`), behalten ihren `path` im Lockfile wieder, nach einer Integritäts-Pin-Regression in 11.6. Und die Auflösung geteilter Package-Kinder ist nun deterministisch, wenn dasselbe Paket über mehrere Kontexte erreicht wird, was eine Klasse von „missing peer"-Reports ([#12358](https://github.com/pnpm/pnpm/issues/12358)) behebt, bei denen das Request-Timing den Kind-Kontext entschied.

Die interaktiven Prompts von `pnpm update -i` und `pnpm audit --fix -i` haben ebenfalls einen UX-Fix erhalten: Die Zusammenfassungszeile nach dem Drücken von Enter druckte zuvor die vollständige Tabellenzeile jeder ausgewählten Auswahl (Label, aktuelle/Ziel-Versionen, Workspace, URL), mit Kommas verbunden, was eine Textwand erzeugte. Die Zusammenfassung listet nun nur die ausgewählten Package-Namen (oder Vulnerability-Keys) auf. Das ist eine Kleinigkeit, aber genau die Art von Polish, die ein 11.7-Minor-Release von einem 11.6-Patch unterscheidet.
