Featured image of post Potenzielle Ziele für Supply Chain Attacks finden

Potenzielle Ziele für Supply Chain Attacks finden

Open-Source-Paket-Registries spielen eine entscheidende Rolle, da sie unkomplizierte Softwareentwicklung ermöglichen. Gleichzeitig erhöhen sie jedoch das Risiko von Supply-Chain-Angriffen, bei denen ein Angreifer ein weniger überwacht oder schlecht gewartetes Paket tief im Abhängigkeitsbaum ins Visier nimmt und bösartigen Code einschleust, der sich weit verbreiten kann. Um jene potenziell angreifbaren Pakete aufzuspüren, habe ich ein kleines Tool geschrieben.

npm hostet über eine Million Pakete, viele davon mit komplexen gegenseitigen Abhängigkeiten. Während populäre Pakete häufig zügig aktualisiert und sicherheitstechnisch überprüft werden, können kleinere oder weniger sichtbare Pakete schnell in Vergessenheit geraten. Angreifer nutzen genau diese „versteckten“ Pakete aus, um weite Teile des Ökosystems zu kompromittieren. npm-target-finder zielt darauf ab, Pakete zu identifizieren, die bestimmte Kriterien erfüllen – etwa hohe Downloadzahlen bei geringer Wartungsressource – und damit attraktive Angriffspunkte für Supply-Chain-Angriffe darstellen. Durch die Fokussierung auf diese Pakete können Entwickler proaktiv Auditierungen durchführen oder Sicherheitslücken beheben, bevor ein Angreifer zuschlägt.

Datenerhebung (getter.js)

Im Kern von npm-target-finder steht ein Node.js-Skript namens getter.js, das automatisiert Metadaten von npm und GitHub sammelt. Folgende Informationen werden dabei erfasst:

  • Paketname
  • Anzahl der Maintainer (Betreuer) im npm-Registry
  • Durchschnittliche tägliche Downloads (npm)
  • Anzahl der Tage seit dem letzten Commit im zugehörigen GitHub-Repository
  • Anzahl offener Pull Requests auf GitHub
  • Anzahl offener Issues auf GitHub
  • Anzahl der GitHub-Sterne

Eine minimale Schwelle für tägliche Downloads (Standard: 1.000) lässt sich in getter.js anpassen, um Pakete mit sehr geringer Nutzung herauszufiltern. Das Ergebnis dieser Datenerhebung ist eine Datei packages.txt, in der jede Zeile die Metadaten eines Pakets enthält.

Beispielhafter Ausschnitt aus getter.js

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
// Pseudocode zur Veranschaulichung der gesammelten Metadaten
{
  pkg: 'beispiel-paket',
  maintainer_count: 2,
  avg_daily: 15000,
  days_since_commit: 120,
  open_prs: 3,
  open_issues: 5,
  stars: 45,
  repo_url: 'https://github.com/autor/beispiel-paket'
}

Diese konsolidierten Daten ermöglichen es, Pakete herauszufiltern, die zwar viele Nutzer haben, aber wenig aktive Wartung erfahren.

Scoring-Mechanismus (score-calculator.py)

Sobald packages.txt generiert wurde, übernimmt das Python-Skript score-calculator.py. Es liest jede Zeile der Metadaten ein und weist jedem Paket einen Score zu, basierend auf konfigurierbaren Schwellenwerten und Gewichtungen. Folgende Faktoren fließen in die Bewertung ein:

  1. GitHub-Sterne: Ein Indikator für Community-Interesse, gleichzeitig jedoch auch dafür, dass eine Kompromittierung große Aufmerksamkeit erzeugen kann.
  2. Durchschnittliche tägliche Downloads: Pakete mit hohen Downloadzahlen verstärken die potenzielle Auswirkung eines schädlichen Updates.
  3. Tage seit dem letzten Commit: Ein hoher Wert deutet darauf hin, dass das Projekt möglicherweise verwaist ist oder selten aktualisiert wird.
  4. Offene Pull Requests: Ein großer Backlog kann darauf hinweisen, dass sicherheitsrelevante Updates ins Stocken geraten.
  5. Offene Issues: Viele ungelöste Probleme können zeigen, dass die Maintainer überlastet sind.

Die Gewichtung und Schwellenwerte (z. B. Anzahl Sterne, Downloads, Commit-Alter etc.) sind im Skript score-calculator.py anpassbar. Nach der Berechnung sortiert das Skript die Pakete nach ihrem Score und gibt die Top 20 der höchsten Risikokandidaten aus, sodass sich Sicherheitsteams genau auf diese konzentrieren können.

Beispielhafte Scoring-Konfiguration (Auszug)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
# Schwellenwerte (modifizierbar)
STAR_THRESHOLD = 100
DOWNLOAD_THRESHOLD = 1000
COMMIT_THRESHOLD_DAYS = 180
OPEN_PRS_THRESHOLD = 2
OPEN_ISSUES_THRESHOLD = 5

# Pseudocode zur Normierung individueller Metriken
score = (
    (avg_daily_downloads / DOWNLOAD_THRESHOLD) * download_weight +
    (stars / STAR_THRESHOLD) * star_weight +
    (days_since_commit / COMMIT_THRESHOLD_DAYS) * staleness_weight +
    (open_prs / OPEN_PRS_THRESHOLD) * pr_weight +
    (open_issues / OPEN_ISSUES_THRESHOLD) * issues_weight
)

Durch das Durchlaufen aller gesammelten Pakete macht das Skript deutlich, welche Pakete einerseits stark genutzt, andererseits wenig aktiv gewartet werden – genau die Merkmale, die für Angreifer attraktiv sind.

Installation

Die Installation und Nutzung von npm-target-finder gestaltet sich wie folgt:

  1. Repository klonen

    1
    2
    
    git clone https://github.com/dheidemann/npm-target-finder.git
    cd npm-target-finder
    
  2. Abhängigkeiten für getter.js installieren

    1
    
    npm install
    
  3. (Optional) GitHub-Token setzen Durch das Setzen einer Umgebungsvariablen GITHUB_TOKEN erhöht sich die API-Rate-Limit deutlich:

    1
    
    export GITHUB_TOKEN=ghp_XXX
    
  4. getter.js ausführen Dieser Schritt kann je nach Rate-Limits und Netzwerkbedingungen mehrere Stunden dauern (in früheren Läufen wurden bis zu fünf Stunden beobachtet):

    1
    
    node getter.js
    

    Nach Abschluss liegt die Datei packages.txt im Projektverzeichnis.

  5. score-calculator.py ausführen Stelle sicher, dass Python 3 installiert ist, und führe dann aus:

    1
    
    python3 score-calculator.py packages.txt
    

    Das Skript gibt die Top 20 Pakete mit jeweils allen Metadaten und dem berechneten Score in der Konsole aus.

Beispielausgabe

1
2
3
4
{'pkg': 'inherits', 'maintainer_count': 1, 'avg_daily': 1078414, 'days_since_commit': 571,
 'open_prs': 2, 'open_issues': 4, 'stars': 353, 'repo_url': 'https://github.com/isaacs/inherits',
 'score': 37.39}
...

Diese Ergebnisse zeigen beispielsweise, dass Pakete wie inherits, isarray und isstream tief in vielen Abhängigkeitsbäumen liegen, nur wenige Maintainer haben und Wartungspausen aufweisen – ideale Kandidaten für eine genauere Prüfung.

Interpretation der Ergebnisse

  • Hoher Score: Ein hoher numerischer Wert deutet auf eine Kombination aus großer Nutzung (Downloads) und problematischen Wartungsindikatoren (z. B. lange Zeit seit dem letzten Commit, viele offene Issues/PRs) hin.
  • Geringe Maintainer-Anzahl: Ein kleines Team bei gleichzeitig hoher Verbreitung kann kaum rasch auf Sicherheitsvorfälle reagieren.
  • Tage seit letztem Commit: Wenn seit dem letzten Commit bereits über ein Jahr vergangen ist, könnte das Projekt faktisch aufgegeben sein.
  • Offene PRs und Issues: Ein großer Rückstau, insbesondere bei sicherheitsrelevanten Anfragen, deutet auf Überlastung der Maintainer hin.

Mithilfe dieses Berichts kann man:

  1. Den Code des Pakets proaktiv auf Schwachstellen prüfen.
  2. Kontakt zu Maintainern aufnehmen und zu zeitnahem Mergework ermutigen.
  3. Forks erstellen oder auf alternative, besser gewartete Bibliotheken migrieren.
  4. Monitoring-Tools (z. B. GitHub Dependabot) gezielt für diese hoch bewerteten Pakete aktivieren.

Anpassungsmöglichkeiten und Feintuning

Die voreingestellten Schwellenwerte und Gewichtungen in score-calculator.py dienen als Basis. Je nach Risikotoleranz eines Unternehmens kann man Folgendes anpassen:

  • Download-Schwelle erhöhen: Manchmal sind nur Pakete mit 10.000+ täglichen Downloads relevant.
  • Stagnationsgewicht erhöhen: Wenn vor allem verwaiste Pakete ein Problem darstellen, sollte man days_since_commit stärker gewichten.
  • Zusätzliche Metriken einbeziehen: Denkbar sind etwa die Integration von Sicherheitshinweisen (Security Advisories), das Datum der letzten Veröffentlichung auf npm oder sogar eine automatisierte Suche nach CVE-Einträgen.

Da das Python-Skript lediglich packages.txt einliest, lassen sich diese Daten auch vorher mit externen Tools (z. B. Shell-Skripte, Pandas) filtern oder ergänzen, bevor das Scoring ausgeführt wird.

Fazit

npm-target-finder adressiert eine wichtige Lücke im Werkzeugkasten für Open-Source-Sicherheit. Durch die automatisierte Identifikation von npm-Paketen, die einerseits weit verbreitet und andererseits nur schwach gewartet sind, lenkt es die Aufmerksamkeit auf jene Projekte, die im Falle einer Kompromittierung großen Schaden anrichten könnten. Ob man als Sicherheitsforscher Einblicke in die npm-Supply-Chain gewinnen möchte oder als Entwicklerteam proaktiv eigene Abhängigkeiten absichern will – npm-target-finder liefert einen einfach adaptierbaren Ansatz, um potenzielle Schwachstellen im Open-Source-Ökosystem sichtbar zu machen.

Erstellt mit Hugo
Theme Stack gestaltet von Jimmy