Transitive Abhängigkeiten mit PNPM upgraden: Beheben Sie Sicherheitslücken, ohne etwas zu zerstören
Das Beheben von Sicherheitslücken kann eine frustrierende Aufgabe sein, insbesondere wenn es sich um transitive Abhängigkeiten handelt. Erfahren Sie, wie Sie diese upgraden können, ohne Ihre direkten Abhängigkeiten zu beeinträchtigen.
Heutzutage sind Sicherheitslücken ein häufiges Problem in der Softwareentwicklung. Zum Glück haben wir Werkzeuge wie GitHub Dependabot, die uns helfen, unsere Abhängigkeiten mit automatischer Erkennung und Pull-Requests auf dem neuesten Stand zu halten.
Allerdings funktioniert es nicht immer wie erwartet. Da einige Abhängigkeiten transitiv sind, kann deren Upgrade für diese Tools eine schwierige Aufgabe sein, da sie die Auswirkungen der Änderungen und die zu treffenden Entscheidungen bei Konflikten nicht kennen. Wir müssen diese Fälle manuell behandeln.
Methoden, die nicht funktionieren
- Offizielle Befehle wie
pnpm up
werden Ihrepnpm-lock.yaml
-Datei durcheinander bringen. Es gibt ein Problem dazu, das zum Zeitpunkt des Schreibens noch offen ist. - Das Installieren der neuesten Version der direkten Abhängigkeit, die die Zieltransitive Abhängigkeit enthält, funktioniert möglicherweise nicht. Wenn die direkte Abhängigkeit die Versionsdefinitionen nicht aktualisiert hat, wird die transitive Abhängigkeit nicht aktualisiert, da sie in der
pnpm-lock.yaml
-Datei aufgelöst und gesperrt wurde.
Die Lösung
Das overrides
-Feld ist eine leistungsstarke Funktion in PNPM, die es Ihnen ermöglicht, einige Versionsauflösungen zu überschreiben. Wir werden diese Funktion nutzen, um transitive Abhängigkeiten zu upgraden und die Änderungen so minimal wie möglich zu halten.
Nehmen wir die oben erwähnte Dependabot-Benachrichtigung als Beispiel. Sie weist darauf hin, dass das follow-redirects
-Paket eine Sicherheitslücke hat und die gepatchte Version 1.15.6
ist. Allerdings verwendet die direkte Abhängigkeit gatsby
axios
, das von [email protected]
abhängt.
Schritt 1: Finden der transitiven Abhängigkeit
Es gibt viele Möglichkeiten, die transitive Abhängigkeit zu finden, aber ich würde die einfachste Methode empfehlen: Durchsuchen Sie die pnpm-lock.yaml
-Datei.
Wie wäre es mit "pnpm why"?
Der Befehl pnpm why <package>
ist in der Tat nützlich. Allerdings könnte er in diesem Fall für Verwirrung sorgen. Wenn ich zum Beispiel pnpm why follow-redirects
ausführe, sieht ein Teil der Ausgabe so aus:
Tatsächlich gibt es in der pnpm-lock.yaml
-Datei nur eine Auflösung für follow-redirects
. Der Befehl pnpm why
kann Ihnen jedoch mehrere Pfade anzeigen, die von derselben Version des Pakets abhängen.
Schritt 2: Hinzufügen der Overrides
Der einfachste Fall ist, dass nur eine Auflösung in der pnpm-lock.yaml
-Datei existiert. Sie können das Override direkt zur package.json
-Datei hinzufügen:
Wenn Sie in einem Workspace arbeiten, sollten Sie das Override zur package.json
-Datei im Root des Workspaces hinzufügen.
Schritt 3: Änderungen anwenden
Führen Sie pnpm install
aus, um die Änderungen anzuwenden. Wir können sehen, dass das follow-redirects
-Paket auf 1.15.6
in der pnpm-lock.yaml
-Datei mit minimalen Änderungen aktualisiert wird.
Nun können Sie das overrides
-Feld aus der package.json
-Datei entfernen, um sie sauber zu halten. Führen Sie dann erneut pnpm install
aus, um zu überprüfen, ob die Änderungen ohne das overrides
-Feld angewendet werden können.
Fehlerbehebung
Die obigen Schritte sind der Idealfall. Es kann jedoch vorkommen, dass nicht immer alles wie erwartet verläuft. Hier sind einige Tipps zur Fehlerbehebung:
Die Version wird nach dem Entfernen des "overrides"-Feldes zurückgesetzt
Dies kann passieren, wenn das abhängige Paket eine feste Version oder einen Bereich hat, der die Zielversion nicht einschließt. Überprüfen Sie die package.json
-Datei des abhängigen Pakets, in diesem Fall axios
, um zu sehen, ob dies zutrifft.
Wenn ja, müssen Sie das overrides
-Feld in der package.json
-Datei behalten, bis das abhängige Paket die Versionsdefinitionen aktualisiert.
Es gibt mehrere Auflösungen für die transitive Abhängigkeit
Mit zunehmendem Projektumfang kann die pnpm-lock.yaml
-Datei mit mehreren Auflösungen für dasselbe Paket gefüllt werden. Zum Beispiel können zwei Hauptversionen desselben Pakets foo
existieren:
Der Bericht über die Sicherheitslücke zeigt, dass [email protected]
ein Sicherheitsproblem aufweist, das in 1.0.1
behoben wurde, und [email protected]
nicht betroffen ist. Wir konnten nicht einfach ein Override für foo
hinzufügen:
- Wenn wir ein Override
"foo": "^1.0.1"
hinzufügen, wird[email protected]
auf1.0.1
herabgestuft. Dies könnte das Projekt zerstören, da[email protected]
möglicherweise neue Funktionen hat, die in den abhängigen Paketen verwendet werden. - Wenn wir ein Override
"foo": "^2.0.0"
hinzufügen, wird[email protected]
auf2.0.0
aktualisiert. Dies könnte das Projekt zerstören, da[email protected]
möglicherweise Breaking Changes aufweist.
Angenommen, foo
folgt dem Semantic Versioning, können wir ein Override wie folgt hinzufügen:
Dies wird nur [email protected]
auf 1.0.1
aktualisieren und [email protected]
unverändert lassen.
Fazit
Bevor PNPM das direkte Upgrade transitiver Abhängigkeiten unterstützt, ist das overrides
-Feld eine gute Lösung, um Sicherheitslücken zu beheben, ohne Dinge zu zerstören. Ich hoffe, dieser Artikel hilft Ihnen, diese Fälle effizienter zu handhaben. Bei Logto verwenden wir diese Methode, um unsere Abhängigkeiten auf dem neuesten Stand und sicher zu halten.