Sie haben ein Paket über npm installiert, das npm-Audit Ausgabe sah einwandfrei aus, und Sie haben weitergemacht.
Sechs Monate später. Du lädst die neuesten Änderungen herunter, in der CI leuchtet eine Warnung auf, und nun brauchst du eine klare Antwort zu einer Abhängigkeit: Ist tslib tatsächlich ein Problem in diesem Baum? Den gesamten Audit-Bericht nach dieser einen Antwort zu durchforsten, ist reine Zeitverschwendung.
Das moderne npm kann diese Frage direkter beantworten. Sie können den Abhängigkeitsbaum mit einem Schwachstellen-Selektor abfragen und strukturierte Audit-Daten mit jqstrukturierte Audit-Daten filtern oder auf einfache Terminal-Tools zurückgreifen, wenn Sie nur einen groben Überblick benötigen. Anschließend können Sie genau nachvollziehen, warum das Paket überhaupt installiert ist.
Hier sind vier Möglichkeiten, ein einzelnes npm-Paket zu überprüfen – in der Reihenfolge, in der Sie sie nutzen sollten.
Hinweis: Die folgenden Befehle wurden mit npm 10.9.7 und npm 12.0.1 getestet. Selektoren und Ausgabeformate ändern sich zwischen den Hauptversionen von npm, führen Sie daher npm -v aus, bevor Sie dies in ein Skript integrieren.
1. Das Paket direkt mit npm query
npm query durchläuft Ihren installierten Abhängigkeitsbaum mithilfe von Abhängigkeitsselektoren im CSS-Stil. Zwei davon übernehmen hier die Arbeit: #tslib passt auf Pakete mit dem Namen tslibab, und :vuln schränkt die Ergebnisse auf Instanzen mit einem bekannten Sicherheitshinweis ein.
npm query '#tslib:vuln'
Ein leeres Array bedeutet, dass npm in den abgefragten Baum- und Registrierungsdaten keine Instanz dieses Pakets gefunden hat, die mit einem bekannten Sicherheitshinweis übereinstimmt. Ein gefülltes Array bedeutet, dass dies der Fall war, und jeder Eintrag enthält detaillierte Metadaten zum Paket und zum Abhängigkeitsbaum sowie einen Feld angibt, wo sich diese Kopie unter node_moduleszu finden ist.
Dieser Metadaten-Dump enthält für eine einzige Frage sehr viel JSON. Kürze ihn mit jq:
npm query '#tslib:vuln' | jq '.[] | {location, version, advisories: [.queryContext.advisories[] | {severity, title}]}'
Die :vuln Selektor fügt jeden passenden Hinweis dem Knoten unter queryContext.advisoriesan, sodass Sie Schweregrad, Titel, CVSS-Wert, CWE und den betroffenen Versionsbereich ohne einen zweiten Befehl erhalten – und zwar alle, nicht nur den ersten.
Sie können im Selektor nach Schweregrad filtern, was hilfreich ist, wenn die Baumstruktur unübersichtlich ist:
npm query ':vuln([severity=high])'
Ein Hinweis: Bei der Filterung nach Schweregrad werden nur Einträge berücksichtigt, die genau diesem Schweregrad entsprechen – weder höhere noch niedrigere. [severity=high] zeigt Ihnen keine kritischen Befunde an. Übergeben Sie sie als Liste, wenn Sie beides möchten:
npm query ':vuln([severity=critical],[severity=high])'
Selektoren lassen sich kombinieren, sodass Sie die Überprüfung auf Ihren Produktionsbaum beschränken können, anstatt auf ein Flag zurückzugreifen:
npm query '.prod#tslib:vuln' # dieses Paket, nur Produktionszweig npm query '.prod:vuln' # alle anfälligen Elemente im Produktionsbaum
Zwei weitere Dinge, die Sie wissen sollten, bevor Sie dies in der Automatisierung einsetzen. :vuln sowie :outdated greifen beide auf die Registry zu, daher funktioniert keines der beiden offline. Und das #name@version , das man noch in älterer Dokumentation findet, wird nicht mehr ausgewertet – npm 12 lehnt #[email protected] mit einem EQUERYNODEPTYPE -Fehler ab. Verwenden Sie stattdessen den Semver-Pseudo-Selektor:
npm query '#tslib:semver(2.4.0)'
Die :vuln Selektor wurde in npm 10.5.0 eingeführt. Wenn Sie sich nicht sicher sind, welche Version Sie verwenden, sollten Sie dies überprüfen, anstatt zu raten:
npm query ':vuln' >/dev/null 2>&1 && echo "unterstützt" || echo "npm aktualisieren"
Bei älteren Versionen springen Sie bitte zum jq -Methode.
2. Filter npm audit JSON mit jq
npm audit stammt noch aus npm 6, während :vuln npm 10.5.0 oder höher erfordert. Daher ist „audit JSON“ die sicherere Wahl für ein gemeinsames Repo, in dem Mitwirkende möglicherweise ältere npm-Versionen verwenden.
npm audit --json | jq '.vulnerabilities["tslib"]'
Die –json gibt maschinenlesbare Audit-Daten anstelle einer formatierten Tabelle zurück. Bei npm 7 und höher enthält dieser Bericht eine Objekt mit dem Namen „vulnerabilities“, Objekt, das nach Paketnamen indiziert ist, sodass der obige Filter den Eintrag für tslib direkt ab. Rufen Sie die Felder ab, die tatsächlich für eine Entscheidung ausschlaggebend sind:
npm audit --json | jq '.vulnerabilities["tslib"] | {severity, range, fixAvailable}'
Read the top-level range as the aggregate vulnerable range for that entry. Do not reach into .via[0].range to get it. The via array mixes advisory objects with bare package-name strings for vulnerabilities inherited through a parent, and even when via[0] happens to be an object it often carries a narrower range than the entry as a whole – on a test tree, express reported <4.20.0 from via[0] against an aggregate range of <=4.21.2 || 5.0.0-alpha.1 – 5.0.0. Silently wrong is worse than empty.
Wenn Sie direkte Hinweise von vererbten unterscheiden möchten, fragen Sie nach über ausdrücklich anfordern und selbst lesen:
npm audit --json | jq '.vulnerabilities["tslib"] | {severity, range, via, fixAvailable}'
Verwenden Sie die Klammer-Syntax anstelle von .vulnerabilities.tslib. Das kostet nur zwei Zeichen und ist die einzige Form, die bei einem in einem Scope stehenden Paketnamen funktioniert, während die Punktnotation bei @ und dem /:
npm audit --json | jq '.vulnerabilities["@babel/traverse"]'
Um alle markierten Elemente anzuzeigen, bevor man sich Paket für Paket ansieht:
npm audit --json | jq -r '.vulnerabilities | keys[]'
null bedeutet nicht, dass keine Sicherheitslücke vorliegt
Wenn der Filter null, dann wissen Sie lediglich, dass der Bericht unter diesem Schlüssel keinen Eintrag enthält. Vier verschiedene Situationen führen zu demselben null:
- Für die installierte Version gibt es in den von npm abgefragten Daten keinen Hinweis.
- Das Paket ist nicht Teil des geprüften Baums.
- Das Paket wurde aus der Prüfung ausgeschlossen, beispielsweise durch –omit=dev.
- Der Name des Pakets wurde falsch eingegeben.
Lassen Sie das Ergebnis aussagekräftig sein, anstatt zu raten:
npm audit --json | jq '.vulnerabilities["tslib"] // "kein Eintrag im Audit-Bericht"'
Überprüfen Sie anschließend anhand der Anleitung in Abschnitt 4, ob das Paket tatsächlich installiert ist.
Falls Sie den Build hier sperren
Der Exit-Code wird Sie in die Irre führen. npm audit gibt immer den Wert 1 zurück, sobald irgendwo in der Struktur eine Schwachstelle gefunden wird, die der konfigurierten Prüfstufe entspricht oder darüber liegt – das sagt nichts über das von Ihnen angefragte Paket aus. Wenn Sie den Schwellenwert mit –audit-level=high ändert nichts daran, wann der Befehl fehlschlägt; es werden keine Befunde mit niedrigerem Schweregrad aus dem Bericht entfernt, der in beiden Fällen identisch bleibt.
npm query verhält sich hier besser: Es gibt den Status 0 zurück, unabhängig davon, ob etwas gefunden wird oder nicht, sodass man die Ergebnismenge selbst als Bedingung verwenden kann.
wenn [ "$(npm query '#tslib:vuln' | jq length)" -gt 0 ]; dann echo "anfällige tslib vorhanden" fi
Wenn Sie sich nur dafür interessieren, was in die Produktion gelangt, führen Sie folgenden Befehl aus: npm audit –omit=dev als Audit-Pfad aus, oder verwende die Option .prod aus Abschnitt 1 für den Abfragepfad. Ein kritischer Befund in einer reinen Build-Abhängigkeit ist etwas anderes als ein solcher in Ihrem Laufzeitbaum.
3. Schnellsuche in menschenlesbaren Ausgaben mit grep
Wenn Sie sich nur einen groben Überblick verschaffen möchten und sich nicht mit JSON beschäftigen wollen, leiten Sie die Standardausgabe mit einem Pipe-Zeichen an grep.
npm audit | grep -A 5 -i "tslib"
Die | Operator übergibt npm auditan grep, das diese zeilenweise durchforstet. -A 5 gibt nach jeder Übereinstimmung fünf Zeilen des nachfolgenden Kontexts aus, wodurch möglicherweise die umgebenden Hinweise erfasst werden. -i macht den Suchvorgang groß-/kleinschreibungsunabhängig.
Das ist heikel, und es lohnt sich, genau zu erklären, warum. Zeilenumbrüche, Layoutänderungen zwischen verschiedenen npm-Versionen und Hinweisblöcke, die länger sind als Ihr Kontextfenster, können den Teil, den Sie benötigen, verdecken. Schlimmer noch: Eine stille Nichtübereinstimmung ist genau in der Weise mehrdeutig, wie „null“ – es könnte „sauber“ bedeuten oder aber, dass Ihr Muster eine umgebrochene Zeile übersehen hat.
Geeignet für eine grobe Einschätzung. Verwenden Sie dies niemals als Beweis dafür, dass ein Paket keine bekannten Sicherheitslücken aufweist.
4. Überprüfen Sie, welche Versionen tatsächlich installiert sind
Ein Audit-Bericht beschreibt den Abhängigkeitsbaum, den npm anhand Ihrer Lockfile-Datei auflöst. Standardmäßig erfordert „npm audit“ erfordert eine „package-lock.json“ oder „shrinkwrap“ an, übermittelt die aufgelösten Paketnamen und Versionen an die Registry und vergleicht sie mit bekannten Sicherheitshinweisen. Es lässt sich sogar mit –package-lock-only und ohne node_modules Verzeichnis überhaupt.
npm ls überprüft den installierten Verzeichnisbaum unter node_modules: npm ls tslib
Der Positionsfilter leistet hier mehr, als man erwarten würde. npm durchläuft den gesamten Baum und gibt den Pfad zu jeder übereinstimmenden Instanz aus, einschließlich verschachtelter Kopien – sodass auch ein Paket, das vier Ebenen tief liegt, angezeigt wird. Durch Hinzufügen von –all ändert diese Ausgabe nicht, wenn du nach Namen filterst (getestet mit npm 10 und npm 12); –all ist genau das, was Sie für ein ungefiltertes npm ls, während die Standardansicht bei den direkten Abhängigkeiten endet.
Rechnen Sie mit Duplikaten. Ein einzelnes Projekt kann leicht drei Kopien desselben Pakets in unterschiedlichen Versionen enthalten, von denen nur einige in den betroffenen Bereich fallen.
Verwende keine Skripte, die gegen die npm ls Exit-Code
npm ls tslib gibt den Status 0 zurück, wenn eine Übereinstimmung gefunden wird, und 1, wenn keine gefunden wird – was wie eine einfache Vorhandenseinsprüfung aussieht. Ganz so ist es jedoch nicht. Wenn das gefundene Paket selbst als ungültig, überflüssig oder fehlend markiert ist, löst npm ELSPROBLEMS aus und beendet sich mit dem Status 1, während es dennoch das gefundene Paket ausgibt. Eine installierte, aber nicht übereinstimmende Abhängigkeit wird als „nicht installiert“ angezeigt:
`– Ungültige `[email protected]: „0.0.8“ aus dem Stammprojekt
npm-Fehlercode ELSPROBLEMS
Unabhängige Probleme an anderen Stellen im Baum haben den gefilterten Exit-Code bei den Tests nicht verfälscht, daher ist das Problem enger gefasst, als es zunächst klingt – aber genau darauf wirst du wahrscheinlich stoßen, wenn du einer Versionsinkongruenz auf der Spur bist. Bei Skripten zähle die Übereinstimmungen mit npm query , das unabhängig vom Zustand des Verzeichnisbaums den Exit-Code 0 zurückgibt und auch verschachtelte Kopien findet:
[ "$(npm query '#tslib' | jq length)" -gt 0 ] && echo "installiert" || echo "nicht installiert"
Aufruf von npm ls –json nach .dependencies[„tslib“] ist eine verlockende Alternative und zugleich eine Falle: Transitive Pakete sind unter ihren übergeordneten Paketen verschachtelt, sodass eine Suche auf oberster Ebene ein Paket als nicht vorhanden meldet, wenn es sich zwei Ebenen tiefer befindet.
Noch etwas: Die Sperrdatei und „node_modules“ driften ständig auseinander. Führen Sie nach dem Abrufen der Änderungen npm ci aus, bevor du den lokalen Baum als maßgeblich betrachtest.
Bonus: Erfahren Sie, warum das Paket installiert wurde
Wenn sich das markierte Paket nicht in Ihrer eigenen „package.json“enthält, wurde es von einer anderen Quelle hinzugefügt. Führen Sie folgenden Befehl im Projektstammverzeichnis aus:
npm explain tslib
npm explain gibt die Abhängigkeitskette für jede passende Installation aus, sodass jede Kopie ihren eigenen Rückverfolgungspfad zum Stammprojekt erhält. Wenn mehrere Kopien vorhanden sind und Sie sich nur für eine interessieren, geben Sie deren Pfad an:
npm explain node_modules/some-package/node_modules/tslib
Dadurch wird die Abhängigkeitskette für diese einzelne Instanz ausgegeben, einschließlich der Fälle, in denen zwei verschiedene übergeordnete Pakete beide vom selben Zwischenpaket abhängen.
Wenn es sich um eine direkte Abhängigkeit handelt → erhöhe die Version selbst. Wenn ein übergeordnetes Modul die Version festlegt → aktualisiere das übergeordnete Modul oder füge einen Überschreibungs-Eintrag Eintrag in „package.json“ (npm 8.3+) als Notlösung hinzu. Ein „override“ erzwingt eine Version, mit der das übergeordnete Paket nie getestet wurde. Behandle es daher als eine Änderung, die von deiner Testsuite abgesichert werden muss, und nicht als eine einzeilige Korrektur.
Was npm audit Ihnen nicht sagen kann
Betrachten Sie all dies eher als grundlegende Triage denn als Programm zur Anwendungssicherheit. Keiner dieser Befehle wird:
- Stellen Sie fest, ob Ihre Anwendung den anfälligen Codepfad erreichen kann.
- Überprüfen Sie die Logik Ihres eigenen Quellcodes.
- Die in einem Paket enthaltenen nativen Binärdateien aussagekräftig analysieren.
- Erkennen Sie ein schädliches oder absichtlich verschleiertes Paket, bevor es jemand meldet.
Der erste Punkt ist besonders wichtig: Die Anzahl der Prüfungsergebnisse entspricht nicht der Anzahl der ausnutzbaren Schwachstellen in Ihrer Anwendung. Und jedes Ergebnis hängt von dem von npm aufgelösten Baum, der von Ihnen konfigurierten Registry und den zum Zeitpunkt der Befehlsausführung verfügbaren Sicherheitshinweisen ab. Wenn Sie dieselbe Prüfung nächste Woche erneut durchführen, erhalten Sie möglicherweise ein anderes Ergebnis, obwohl sich an Ihrem Code nichts geändert hat.
Abschließende Gedanken
Die Kurzfassung, damit Sie es ausprobieren können:
npm query '#tslib:vuln' # Sauberste npm-native-Prüfung npm audit --json | jq '.vulnerabilities["tslib"]' # portabel, skriptfreundlich npm ls tslib # Was ist tatsächlich installiert? npm explain tslib # warum es installiert ist Eine einmalige Überprüfung im Terminal ist nur eine Momentaufnahme, und der Wert des Abhängigkeitsscans liegt in der Wiederholung. Tools zur kontinuierlichen Überwachung – Dependabot, ein Open-Source-Scanner wie OSV-Scanner oder eine kommerzielle Plattform zur Software-Composition-Analyse – decken neu veröffentlichte Sicherheitshinweise zu Code auf, den Sie nicht verändert haben, sorgen dafür, dass die Ergebnisse über alle Repositories hinweg sichtbar bleiben, und automatisieren einen Teil der Upgrade-Arbeit. Was sie jedoch nicht leisten können, ist, die oben genannten Grenzen zu überwinden: Sie stützen sich nach wie vor größtenteils auf Informationen zu bekannten Schwachstellen, und ein nicht gemeldetes bösartiges Paket bleibt auch für sie unsichtbar.
Um genau diese Lücke zu schließen, muss die Überprüfung vor der Veröffentlichung der Sicherheitsempfehlung erfolgen – genau diesen Ansatz verfolgt TuxCare SecureChain for OSS: Es stellt Ihre npm-Abhängigkeiten aus einem kuratierten Repository bereit, in dem Pakete aus dem Quellcode neu kompiliert und überprüft werden, bevor sie überhaupt in Ihrem node_modulesgelangen.
Die Terminalbefehle bleiben dennoch nützlich. Wenn man eine sofortige Antwort zu einem bestimmten Paket in einem Projekt benötigt, sind sie schneller als das Öffnen eines Dashboards.

