NPM-Pakete: Sicherheitsrisiken in JavaScript-Legacy-Projekten verstehen und beheben

Jemand öffnet ein JavaScript-Projekt, das seit Jahren stabil läuft. Er tippt npm install. Und bekommt eine Meldung: "found 214 vulnerabilities (63 moderate, 118 high, 33 critical)".
Diese Zahl schockiert zuerst. Dann passiert meistens nichts.
Das ist verständlich. Die Anwendung läuft. Kunden nutzen sie. Niemand weiß, welche der 214 Meldungen wirklich gefährlich sind. Und niemand will ein funktionierendes System kaputt machen.
Genau hier setzt dieser Artikel an. npm-Pakete sind der Teil Ihrer Software, den niemand geschrieben hat, für den Sie aber trotzdem haften. Wir zeigen Ihnen, wie diese Risiken entstehen. Und in welcher Reihenfolge Sie sie sinnvoll abarbeiten.
Was npm-Pakete sind und warum es so viele werden
npm steht für "Node Package Manager". Es ist die zentrale Bezugsquelle für fertige JavaScript-Bausteine. Diese Bausteine heißen Pakete.
Ein Entwickler braucht eine Datumsfunktion. Statt sie selbst zu schreiben, bindet er ein Paket ein. Das spart Zeit und ist völlig normal.
Das Problem beginnt eine Ebene tiefer. Dieses Paket bringt seine eigenen Abhängigkeiten mit. Und die wiederum ihre eigenen.
Aus 20 bewusst gewählten Paketen werden so schnell 900 installierte. Fachleute nennen diese indirekten Pakete "transitive Abhängigkeiten". Was eine Abhängigkeit genau ist, erklären wir in unserem Glossar.
Sie haben diese 880 zusätzlichen Pakete nie ausgewählt. Sie sind trotzdem Teil Ihrer Anwendung.
Wie Sicherheitslücken in npm-Paketen entstehen
Der Code bleibt stehen, die Forschung geht weiter
Ein Paket aus dem Jahr 2018 ist nicht schlecht, nur weil es alt ist. Es war damals sauber programmiert.
Aber Sicherheitsforscher arbeiten weiter. Sie finden Schwachstellen in Bibliotheken, die jahrelang als unauffällig galten. Diese Funde landen in öffentlichen Datenbanken.
Ihr Code ändert sich nicht. Das Wissen über seine Schwachstellen schon.
Aufgegebene Pakete ohne Betreuer
Viele npm-Pakete werden von einzelnen Personen in ihrer Freizeit gepflegt. Menschen wechseln den Job. Sie verlieren das Interesse.
Das Paket bleibt online. Es funktioniert weiter. Aber niemand schließt gemeldete Lücken.
In Altprojekten finden wir regelmäßig Pakete, deren letztes Update sechs Jahre zurückliegt. Das ist kein Vorwurf an die Entwickler von damals. Es ist einfach der Zustand, den es zu kennen gilt.
Die Lockfile friert alles ein
Eine Datei namens package-lock.json legt exakt fest, welche Version jedes Pakets installiert wird. Das ist eine gute Sache. Sie sorgt dafür, dass die Anwendung überall gleich läuft.
Die Kehrseite: Ohne aktive Pflege bleibt dieser Stand für immer eingefroren. Ein Projekt von 2019 installiert auch 2026 noch die Versionen von 2019.
Was passiert, wenn Sie nichts tun
Die ehrliche Antwort lautet: meistens jahrelang nichts. Und dann alles auf einmal.
Automatisierte Angriffe. Angreifer suchen selten gezielt Ihr Unternehmen. Sie scannen das Internet nach bekannten Signaturen verwundbarer Bibliotheken. Eine dokumentierte Lücke ist eine Einladung mit Bauanleitung.
Der Berg wächst schneller als er schrumpft. Jedes Jahr ohne Updates macht das spätere Aufholen teurer. Aus einem Versionssprung werden vier. Aus einem Nachmittag wird ein Projekt.
Compliance-Fragen. Die DSGVO verlangt technische Maßnahmen nach dem Stand der Technik. Eine Anwendung mit 33 kritischen und öffentlich dokumentierten Lücken erfüllt das schwer. Nach einem Vorfall wird genau danach gefragt.
Blockade bei neuen Anforderungen. Irgendwann kommt eine neue Funktion. Oder eine neue Node-Version auf dem Server. Dann muss das Update ohnehin passieren, nur unter Zeitdruck.
So finden Sie die Schwachstellen
npm audit ist der erste Schritt
Der Befehl npm audit gehört zu npm dazu. Er vergleicht Ihre installierten Pakete mit einer öffentlichen Schwachstellendatenbank.
Sie brauchen dafür kein zusätzliches Werkzeug und keinen Vertrag. Ein Terminal genügt.
Mit npm audit --json bekommen Sie eine maschinenlesbare Liste. Die ist deutlich brauchbarer als die bunte Ausgabe im Terminal.
Wichtig: Bei sehr alten Projekten funktioniert der Befehl manchmal nicht mehr. Dann fehlt oft eine package-lock.json. Diese lässt sich mit npm install --package-lock-only nachträglich erzeugen.
Die Zahl allein sagt wenig
214 Schwachstellen klingen dramatisch. Oft entfallen 180 davon auf Werkzeuge, die nur beim Bauen der Anwendung laufen.
Diese sogenannten devDependencies landen nie auf Ihrem Server. Ein Angreifer aus dem Internet erreicht sie nicht.
Trennen Sie deshalb immer zwischen Produktivbetrieb und Entwicklungswerkzeugen. Diese eine Unterscheidung reduziert die Liste häufig um zwei Drittel.
Eine zweite Meinung einholen
npm audit hat blinde Flecken. Es meldet nur, was in der npm-Datenbank steht.
Werkzeuge wie OSV-Scanner, Trivy oder Dependabot greifen auf weitere Quellen zu. Ein Abgleich lohnt sich, besonders vor einem Audit oder einer Übernahme.
Wie sich solche Meldungen dauerhaft überwachen lassen, beschreiben wir im Artikel zum CVE-Monitoring.
So beheben Sie die wichtigsten Lücken zuerst
Schritt 1: Erreichbarkeit vor Schweregrad
Die Einstufung "critical" bezieht sich auf die Lücke an sich. Nicht auf Ihre Anwendung.
Fragen Sie stattdessen: Wird der betroffene Code bei uns überhaupt aufgerufen? Verarbeitet er Eingaben von außen?
Eine kritische Lücke in ungenutztem Code ist weniger dringend. Eine mittlere Lücke in Ihrer Login-Verarbeitung ist es sehr wohl. Diese Einordnung braucht Erfahrung, spart aber enorm viel Aufwand.
Schritt 2: Die einfachen Fälle abräumen
npm audit fix aktualisiert alle Pakete, bei denen das ohne Bruch möglich ist. Es bleibt dabei innerhalb kompatibler Versionen.
Dieser Befehl erledigt oft ein Drittel der Meldungen in wenigen Minuten. Führen Sie ihn aus, testen Sie die Anwendung, machen Sie einen eigenen Commit daraus.
Finger weg von npm audit fix --force ohne Prüfung. Dieser Zusatz erzwingt auch Sprünge über Hauptversionen. Er hat schon viele laufende Anwendungen zum Stillstand gebracht.
Schritt 3: Transitive Pakete gezielt anheben
Manchmal steckt die Lücke drei Ebenen tief. Das direkte Paket lässt sich nicht aktualisieren, weil es das alte Unterpaket festschreibt.
Für solche Fälle gibt es das Feld overrides in der package.json. Damit erzwingen Sie eine bestimmte Version des Unterpakets.
Das ist ein Werkzeug für den Übergang, keine Dauerlösung. Notieren Sie jede Ausnahme, damit sie später nicht vergessen wird.
Schritt 4: Große Sprünge einzeln planen
Wenn ein Framework von Version 2 auf Version 5 muss, ist das kein Update mehr. Das ist ein kleines Projekt.
Nehmen Sie sich diese Pakete einzeln vor. Ein Paket, ein Zweig, ein Test, ein Commit. So bleibt jederzeit nachvollziehbar, was ein Problem verursacht hat.
Bei größeren Vorhaben hilft ein strukturiertes Vorgehen, wie wir es beim Abbau technischer Schulden beschreiben.
Schritt 5: Verwaiste Pakete ersetzen
Manche Pakete bekommen kein Update mehr, weil sie niemand mehr betreut. Hier hilft nur der Austausch.
Häufig gibt es einen benannten Nachfolger. Manchmal löst inzwischen eine eingebaute Funktion das Problem ganz ohne Paket.
Das ist der aufwändigste Teil. Er ist aber auch der einzige, der die Schulden wirklich tilgt.
Damit sich der Berg nicht neu aufbaut
Ein einmaliges Aufräumen hält etwa ein Jahr. Danach beginnt dieselbe Ansammlung von vorn.
Drei Maßnahmen verhindern das mit wenig Aufwand:
Automatische Meldungen einschalten. Dependabot oder Renovate melden neue Lücken selbstständig und schlagen Updates vor. Beides ist für die meisten Projekte kostenlos.
Einen festen Termin setzen. Ein halber Tag pro Quartal reicht für die meisten Anwendungen. Regelmäßig und klein schlägt selten und groß.
Neue Pakete kurz prüfen. Wann kam das letzte Update? Wie viele Menschen pflegen es? Zwei Minuten Recherche ersparen später viel Arbeit.
Wer diesen Rhythmus nicht selbst halten kann, gibt ihn ab. Genau dafür gibt es unsere laufende Software-Wartung.
Fazit: Zahlen beruhigen nicht, Priorisierung schon
Die Warnung nach npm install verschwindet nicht von allein. Sie wird jedes Jahr länger.
Die gute Nachricht: Sie müssen nicht 214 Meldungen abarbeiten. Sie müssen die zwölf finden, die Ihre Anwendung wirklich betreffen.
Das ist Arbeit, aber es ist planbare Arbeit. Und sie kostet deutlich weniger als ein Sicherheitsvorfall.
Wenn Sie nicht wissen, wo Ihr JavaScript-Projekt steht, schauen wir gemeinsam hin. Wir prüfen Ihre Abhängigkeiten, sortieren die Funde nach echtem Risiko und sagen Ihnen ehrlich, was dringend ist und was warten kann.
Sprechen Sie uns an. Das Erstgespräch ist kostenlos.


