Yarn ist nur bedingt sicher
Tim Kadlec
25. Oktober 2016
0 Min. LesezeitVor einigen Wochen kündigte Facebook die Open-Source-Veröffentlichung von Yarn an: eines neuen Clients für die npm-Registry. Einige äußerten zwar Bedenken, doch Yarn scheint ein solides Beispiel für Open-Source-Entwicklung zu sein. Facebook, Google, Exponent und Tilde standen bei der Verwendung des standardmäßigen npm-Clients vor ähnlichen Herausforderungen. Statt dass jedes Unternehmen eigene Lösungen entwickelte, schlossen sie sich zusammen und bauten auf npm auf. Das Ergebnis ist ein alternativer Client, der einige bemerkenswerte Verbesserungen bietet, ohne die Leistungsfähigkeit der zugrunde liegenden npm-Registry einzubüßen.
Yarn beschreibt sich selbst als „extrem schnell“, „superzuverlässig“ und „meg sicher“. Yarn ist zwar oft deutlich schneller, und die neue Lockdatei sorgt bei der Installation Ihrer Anwendung für mehr Konsistenz. Die Sicherheitsversprechen sind jedoch etwas zu optimistisch.
Was Yarn für die Sicherheit leistet
Wenn Yarn von „mega sicher“ spricht, bezieht sich das darauf, dass Prüfsummen verwendet werden, um sicherzustellen, dass das angeforderte Paket unverändert bei Ihnen ankommt.
Prüfsummenüberprüfung
Sie können sich das ansehen, indem Sie in einem Ihrer Projekte die Datei yarn.lock öffnen. Hier ein Auszug daraus:
Der obige Ausschnitt zeigt, dass wir das Paket moment angefordert haben und das Paket über die folgende URL bezogen wurde:
Besonders interessant ist hier der Abschnitt nach dem Hash:
Dies ist die Prüfsumme der Datei, berechnet mit dem Secure Hash Algorithm 1 (SHA-1). Wenn Sie das Paket über die URL lokal herunterladen, können Sie die Prüfsumme in der Kommandozeile entweder mit dem Befehl sha1sum unter Linux oder mit dem Befehl shasum unter Mac OSX überprüfen.
Diese Befehle geben den SHA-1-Hash aus, der mit dem Hash in der Richtliniendatei übereinstimmt. Angenommen, Sie fordern das Paket an, aber es unterscheidet sich in irgendeiner Weise von dem, was in der Prüfsumme der Datei yarn.lock angegeben ist. Ich habe beispielsweise eine Zeile zur Datei README.md hinzugefügt, das .tgz-Archiv neu erstellt und dann erneut shasum ausgeführt. Der neue Hash lautete:
Dieser neue Hash stimmt nicht mit dem erwarteten Hash überein. Sie können also erkennen, dass sich etwas geändert hat: Das Angeforderte stimmt nicht mit dem Empfangenen überein. Dieses Etwas kann harmlos sein – vielleicht ist bei der Übertragung der Datei ein Fehler aufgetreten und die Datei wurde beschädigt. Es kann aber auch böswillige Absichten haben – vielleicht hat sich ein Angreifer des Pakets bemächtigt und es manipuliert. Die Prüfsumme weist Sie auf einen Fehler hin, damit Sie der Sache weiter nachgehen können.
Wie können Angreifer ein Paket manipulieren?
Die Gewährleistung der Datenintegrität ist zwar eine nützliche Funktion, doch es lohnt sich zu fragen, wie ein Angreifer ein Paket überhaupt manipulieren könnte.
Eine Möglichkeit besteht darin, das Paket direkt an der Quelle zu ändern – in der Registry, in der es gehostet wird. Die meisten Nutzer laden Pakete von npmjs.com herunter. Soweit mir bekannt ist, gab es dort bisher keine Fälle, in denen Angreifer Code direkt auf Registry-Ebene verändert haben.
Die andere Möglichkeit besteht darin, das Paket während des Downloads auf dem Übertragungsweg zu manipulieren. Die meisten Pakete werden ebenfalls aus der öffentlichen npm-Registry heruntergeladen, die HTTPS verwendet. Pakete während der HTTPS-Übertragung zu verändern, ist zwar möglich, aber alles andere als einfach.
Prüfsummen sind nützlicher, wenn Sie eine eigene Registry hosten. Die Angebote von Artifactory und Nexus sind zwar gut abgesichert, doch wenn Sie Ihre eigene Lösung betreiben, kann es Schwachstellen geben, die eine direkte Manipulation von Paketen in der Registry ermöglichen. Und obwohl wir Ihnen dringend davon abraten, haben wir schon lokale Registrys gesehen, die über HTTP bereitgestellt wurden. In solchen Szenarien lassen sich Pakete viel leichter verändern, wodurch Prüfsummen deutlich wichtiger werden.
Wenn Sie die öffentliche npm-Registry verwenden oder Ihre eigene Registry über HTTPS mit einem kommerziellen Angebot hosten, ist die Art von Manipulation, vor der Prüfsummen schützen, weniger problematisch. Es handelt sich um eine Sicherheitsfunktion, aber um eine eher nebensächliche.
yarn.lock für feste Versionen
Außerdem bringt die Datei yarn.lock einen Haken für Ihre Sicherheitspläne mit sich. Wie npm shrinkwrap dient die Datei yarn.lock dazu, bestimmte Versionen Ihrer Abhängigkeiten festzuschreiben. Der Vorteil einer Lockdatei: Wenn ich ein Yarn-Projekt auf meinem Rechner installiere und morgen dieselbe Anwendung in einer Produktionsumgebung installiere, kann ich sicher sein, dass bei beiden Installationen genau dieselben Abhängigkeiten verwendet werden – selbst wenn inzwischen eine neue Version veröffentlicht wurde.
Das ist gut für die Konsistenz, doch Lockdateien sind darauf ausgelegt, die verwendeten Pakete nicht zu aktualisieren. Anders als bei der Verwendung von Semver-Ranges ist ein Upgrade auf eine neue Version einer Abhängigkeit nur möglich, wenn Sie die Lockdatei bearbeiten oder neu erstellen. Entwickler müssen nun selbst darauf achten, Updates im Blick zu behalten, die wichtige Schwachstellen beheben könnten – noch stärker als bei semver-basierten Ansätzen wie dem in package.json.
Das heißt nicht, dass Sie keine Lockdateien verwenden sollten. Wenn Konsistenz für Ihre Anwendung wichtig ist, sollten Sie sie durchaus nutzen. Denken Sie aber daran, die richtigen Maßnahmen zu treffen, damit Sie unsichere Pakete regelmäßig überprüfen und aktualisieren.
Die fehlende Sicherheitskomponente
Prüfsummen bieten eine zusätzliche Sicherheitsebene, tragen aber nicht dazu bei, dass das ursprüngliche Paket, das Sie beziehen möchten, selbst sicher ist. In der Open-Source-Entwicklung ist das ein weitaus größeres Problem. Die meisten Open-Source-Maintainer haben zwar gute Absichten, doch selten wird bei der Entwicklung dieser Pakete Sicherheit als grundlegende Anforderung berücksichtigt. Wenn wir diese Pakete in unsere eigenen Projekte aufnehmen, tun wir das ohne genaue Prüfung – ohne zu wissen, welche Abhängigkeiten sich daraus ergeben und welche Sicherheitsprobleme darin lauern könnten.
Das zuvor betrachtete Paket moment enthält beispielsweise eine Schwachstelle, die einen Denial-of-Service-Angriff durch reguläre Ausdrücke ermöglicht, für die ein Patch verfügbar ist. Wenn Sie das Paket mit Yarn installieren, erfahren Sie davon nichts. Abhängigkeiten auf bekannte Schwachstellen zu überprüfen, ist ein anderes und weitaus größeres Sicherheitsthema als das, was Yarn abdeckt.
Wie werden Sie wirklich meg sicher?
Zum Glück basiert Yarn auf npm und fügt sich daher gut in das Ökosystem ein. Yarn hat derzeit noch einige Schwachstellen, doch sobald diese behoben sind, sollten bestehende Sicherheitstools mit nur minimalen Änderungen funktionieren.
Um bekannte Schwachstellen in npm-Paketen zu beheben, empfehlen wir derzeit beispielsweise, snyk protect als Teil des Schritts post-install in Ihren Node.js-Anwendungen auszuführen. Auch bei yarn install wird dieser Schritt ausgeführt, sodass snyk protect weiterhin läuft und Ihre Abhängigkeiten auf bekannte Schwachstellen überprüft.
Wir finden Yarn ziemlich cool, und angesichts der großen Aufmerksamkeit, die es erhalten hat, scheinen viele unserer Meinung zu sein. Yarn ist in der Regel schneller, und die neuen Lockdateien sind für viele Unternehmen hilfreich, die bei ihren Installationen mehr Konsistenz erreichen möchten.
Es ist zwar großartig, dass Yarn versucht, Sicherheit von Anfang an zu integrieren, doch die Aussage, es sei „mega sicher“, ist etwas zu selbstbewusst. Das Problem sind nicht die Prüfsummen, sondern das Marketing. Prüfsummen tragen dazu bei, die Integrität Ihrer Daten sicherzustellen. Im Node.js-Ökosystem ist das jedoch ein eher nebensächliches Problem. Viel wichtiger ist, von Anfang an sicherzustellen, dass Ihre Abhängigkeiten sicher sind.
Starten Sie mit Capture-the-Flag
Erfahren Sie in unserem virtuellen On-Demand-Workshop für Einsteiger, wie Sie Capture-the-Flag-Challenges lösen.