Dies ist Teil 1 einer zweiteiligen Serie zum Schutz von Astro-Websites vor npm-Supply-Chain-Angriffen. In diesem Artikel geht es um das Verständnis der Bedrohung und unmittelbare Reaktionsmaßnahmen. In Teil 2 finden Sie langfristige Sicherheitsmaßnahmen, Monitoring und Best Practices.
SponsoredHochwertige Starter-Kits mit integriertem Authentifizierungsfluss (Auth.js), Objekt-Uploads (AWS, Clouflare R2, Firebase Storage, Supabase Storage), integrierten Zahlungen (Stripe, LemonSqueezy), E-Mail-Verifizierungsablauf (Resend, Postmark, Sendgrid) und viel mehr . Kompatibel mit jeder Datenbank (Redis, Postgres, MongoDB, SQLite, Firestore).
Get all 3 kits Bundle ↗
Next.js Starter Kit SvelteKit Starter Kit Astro Starter KitOne-time license · Lifetime updates
Im November 2025 erlebte das npm-Ökosystem einen der bislang gravierendsten Supply-Chain-Angriffe: Shai-Hulud 2.0. Der Angriff kompromittierte über 700 npm-Pakete, darunter beliebte Bibliotheken von Zapier, PostHog und Postman, und betraf rund 27 % der Cloud- und Code-Umgebungen. Die Malware wurde während der preinstall-Phase ausgeführt, stahl Zugangsdaten von GitHub, AWS, GCP, Azure und anderen Diensten und exfiltrierte sie in öffentliche Repositories.
Laut Wiz Research wurden über 25.000 bösartige Repositories mit gestohlenen Secrets angelegt; während des Angriffs tauchten neue Repos im Rhythmus von etwa 1.000 alle 30 Minuten auf. Wenn Sie eine Astro-Website betreiben, hilft Ihnen dieser Leitfaden, die Bedrohung zu verstehen und sofort zu handeln.
Voraussetzungen
Sie benötigen Folgendes:
- Node.j 20 oder höher
- Ein bestehendes Astro-Projekt
- Zugriff auf Ihre CI/CD-Pipeline-Konfiguration
- Administratorzugriff auf Ihren Paketmanager (npm, pnpm oder yarn)
1. Den Shai-Hulud-2.0-Angriff verstehen
Beim Shai-Hulud-2.0-Angriff nutzten Angreifer kompromittierte Maintainer-Konten, um trojanisierte Versionen legitimer npm-Pakete zu veröffentlichen. Es handelte sich nicht um eine neue Zero-Day-Schwachstelle oder einen ausgeklügelten Exploit – sondern um die Kompromittierung vertrauenswürdiger Konten, die es den Angreifern ermöglichte, bösartigen Code unter dem Deckmantel legitimer Updates zu veröffentlichen.
1.1 Was macht diesen Angriff anders?
Im Gegensatz zu traditionellen Angriffen wies diese Variante mehrere besorgniserregende Merkmale auf:
1.1.1 Ausführung während der preinstall-Phase
Die Malware lief während des preinstall-Lifecycle-Hooks, was den Schaden erheblich ausweitet. Das bedeutet:
- Sie wird ausgeführt, bevor die Paketinstallation abgeschlossen ist
- Sie läuft auf Entwicklerrechnern während
npm install - Sie wird automatisch in CI/CD-Pipelines ausgeführt
- Sie lässt sich nicht leicht durch typische Sicherheitsmaßnahmen verhindern
// Example of how the malicious package.json looked{ "scripts": { "preinstall": "node malicious-script.js" }}1.1.2 Diebstahl verschiedener Credential-Typen
Der Angriff beschränkte sich nicht auf einen einzelnen Credential-Typ. Er suchte aktiv nach und exfiltrierte:
- GitHub-Tokens: Personal Access Tokens, OAuth-Tokens und Deploy Keys
- AWS-Zugangsdaten: Langzeit-Zugangsschlüssel (AKIA-Format), Secret Keys und Session Tokens
- GCP-Zugangsdaten: Service-Account-Keys und Anwendungs-Credentials
- Azure-Zugangsdaten: Service-Principal-Credentials und Storage Keys
- Umgebungsvariablen: Alle Secrets in
.env-Dateien oder der Umgebung
1.1.3 Cross-Victim-Exfiltration
Einer der heimtückischsten Aspekte: Ihre gestohlenen Daten erscheinen möglicherweise gar nicht in Ihrem eigenen GitHub-Konto:
// Simplified example of the exfiltration logicconst victims = getRandomVictimAccounts()const stolenData = gatherCredentials()
// Upload to ANOTHER victim's accountuploadToGitHub(victims[randomIndex], stolenData)Das bedeutet:
- Ihre Secrets könnten in einem fremden öffentlichen Repository liegen
- Secrets anderer Opfer könnten in Ihrem Konto auftauchen
- Die Erkennung ist deutlich schwieriger
- Der Schaden ist viel größer als zunächst sichtbar
1.1.4 Backdoor-Workflows
Die Malware versuchte, bösartige GitHub-Actions-Workflows für persistenten Zugriff einzuschleusen:
# Example of injected .github/workflows/discussion.yamlname: Discussion Updateon: push: schedule: - cron: '0 */6 * * *'jobs: exfiltrate: runs-on: ubuntu-latest steps: - name: Gather More Secrets run: | # Malicious code here1.1.5 Betroffene weit verbreitete Pakete
Der Angriff zielte auf Pakete ab, die im Ökosystem weit verbreitet sind:
@postman/tunnel-agent– in 27 % der Umgebungen gefundenposthog-node– in 25 % der Umgebungen gefunden@asyncapi/specs– in 20 % der Umgebungen gefunden- Verschiedene Zapier-Platform-Pakete
Das maximierte die Reichweite des Angriffs und konnte Tausende Projekte sofort betreffen.
1.2 Angriffszeitplan und Auswirkungen
Folgendes ist über den Verlauf des Angriffs bekannt:
-
21.–23. November 2025: Erste Kompromittierung und Upload trojanisierter Pakete auf npm
-
24. November 2025 (01:22 UTC): Früheste Hinweise auf GitHub-Repositories mit geleakten Secrets
-
24. November 2025 (~03:00 UTC): Früheste Hinweise auf bösartige Paketversionen auf npm
-
25. November 2025 (22:45 UTC): Mögliche zweite Phase mit Veröffentlichung privater Repositories beobachtet
-
26. November 2025: GitHub beginnt mit Gegenmaßnahmen durch Token-Widerruf und Privatisierung bösartiger Repositories
Auswirkungen in Zahlen:
- ~700 kompromittierte Pakete auf npm
- 25.000+ bösartige Repositories angelegt
- ~500 betroffene GitHub-Nutzer
- 775+ kompromittierte GitHub-Access-Tokens (verifiziert)
- 373+ geleakte AWS-Zugangsdaten
- 300+ exponierte GCP-Zugangsdaten
- 115+ kompromittierte Azure-Zugangsdaten
Die Malware erzeugt spezifische Indikator-Dateien:
cloud.json # Cloud provider credentialscontents.json # Repository contents and codeenvironment.json # Environment variables and secretstruffleSecrets.json # Secrets detected by TruffleHog patternsbun_environment.js # Bun runtime environment datasetup_bun.js # Setup script for persistence2. Sofortmaßnahmen
Wenn Sie vermuten, dass Ihr Astro-Projekt betroffen sein könnte, folgen Sie diesen Schritten unverzüglich. Zeit ist entscheidend – je länger kompromittierte Zugangsdaten aktiv bleiben, desto größer der Schaden.
2.1 Abhängigkeiten prüfen
Prüfen Sie zuerst, ob kompromittierte Pakete in Ihrem Abhängigkeitsbaum vorkommen.
2.1.1 Schnellcheck mit pnpm Audit
# Run a security auditpnpm audit fix
# Or with npmnpm audit --audit-level=moderate2.1.2 Manuelle Inspektion
Überprüfen Sie package.json und Lock-Dateien auf Hochrisiko-Pakete:
# Check for specific compromised packagesgrep -E "@postman/tunnel-agent|posthog-node|posthog-js|@asyncapi/specs|zapier-platform" package.json pnpm-lock.yaml2.1.3 Bekannte kompromittierte Pakete (Auszug)
Hier einige der am weitesten verbreiteten betroffenen Pakete:
{ "high-prevalence-packages": [ "@postman/tunnel-agent", "posthog-node", "posthog-js", "@asyncapi/specs", "@asyncapi/openapi-schema-parser", "zapier-platform-cli", "zapier-platform-core", "zapier-platform-schema", "zapier-async-storage", "get-them-args", "shell-exec", "kill-port" ]}2.1.4 Transitive Abhängigkeiten prüfen
Kompromittierte Pakete sind möglicherweise keine direkten Abhängigkeiten. Prüfen Sie den gesamten Abhängigkeitsbaum:
# For pnpmpnpm list --depth=Infinity | grep -E "postman|posthog|zapier"
# For npmnpm list --all | grep -E "postman|posthog|zapier"2.1.5 Installationsverlauf prüfen
Prüfen Sie, wann Pakete zuletzt installiert wurden, um das Expositionsfenster einzugrenzen:
# Check git history of lock file changesgit log -p --follow pnpm-lock.yaml | grep -A 5 -B 5 "postman\|posthog\|zapier"2.2 Umgebung auditieren
Suchen Sie in Ihrer lokalen Entwicklungsumgebung und in CI/CD-Systemen nach Anzeichen einer Kompromittierung.
2.2.1 Nach bösartigen Dateien scannen
# Check for known malware indicator filesfind . -type f \( \ -name "cloud.json" -o \ -name "contents.json" -o \ -name "environment.json" -o \ -name "truffleSecrets.json" -o \ -name "bun_environment.js" -o \ -name "setup_bun.js" \\) 2>/dev/nullWenn dieser Befehl Ergebnisse liefert, wurde Ihre Umgebung kompromittiert.
2.2.2 GitHub-Workflows prüfen
# List all workflow filesls -la .github/workflows/
# Check for the known malicious workflowcat .github/workflows/discussion.yaml 2>/dev/nullDer bösartige Workflow weist typischerweise auf:
- Name: „Discussion Update“ oder ähnlich
- Verdächtige Cron-Zeitpläne
- Ungewöhnlichen Zugriff auf Umgebungsvariablen
- Base64-kodierte Befehle
2.2.3 Git-Historie auf unautorisierte Änderungen prüfen
# Check recent commits for suspicious changesgit log --all --oneline --decorate --graph -n 20
# Look for unexpected workflow additionsgit log --all --full-history -- .github/workflows/2.2.4 GitHub-Repositories prüfen
Melden Sie sich bei GitHub an und prüfen Sie:
- Unerwartete öffentliche Repositories in Ihrem Konto
- Repositories mit Namen, die geleakte Daten oder Credentials enthalten
- Repository-Beschreibungen mit „Shai-Hulud“ oder verdächtigem Inhalt
- Neu angelegte Repositories, die Sie nicht erstellt haben
2.2.5 CI/CD-Logs prüfen
Prüfen Sie Ihre CI/CD-Pipeline-Logs auf:
- Unerwartete Netzwerkverbindungen während Builds
- Fehlgeschlagene Authentifizierungsversuche
- Ungewöhnliche Paketinstallationen
- Längere Build-Dauer (Malware-Ausführung braucht Zeit)
# Example: Check GitHub Actions logsgh run list --limit 20gh run view <run-id> --log2.3 Alle Zugangsdaten rotieren
Wenn Sie kompromittierte Pakete oder verdächtige Dateien gefunden haben, rotieren Sie sofort alle Zugangsdaten. Warten Sie nicht, bis das volle Ausmaß der Kompromittierung bestätigt ist.
2.3.1 GitHub-Tokens
- Gehen Sie zu GitHub Settings → Developer settings → Personal access tokens
- Prüfen Sie alle vorhandenen Tokens:
- Notieren Sie, wofür jedes Token verwendet wird
- Prüfen Sie das Datum der letzten Nutzung
- Widerrufen Sie ALLE Tokens (auch wenn sie harmlos erscheinen)
- Erstellen Sie neue Tokens mit minimal erforderlichen Berechtigungen:
# Use the principle of least privilege# Instead of:# - repo (full control)# Use:# - repo:status (read-only)# - public_repo (if possible)-
Aktualisieren Sie Tokens in:
- CI/CD-Secrets (GitHub Actions, CircleCI usw.)
- Lokale Entwicklungsumgebungen
- Automatisierungsskripte
- Drittanbieter-Integrationen
2.3.2 AWS-Zugangsdaten
Rotieren Sie AWS-Access-Keys sofort:
# 1. List current access keysaws iam list-access-keys --user-name your-username
# 2. Create new access keys FIRSTaws iam create-access-key --user-name your-username# Save the output immediately - you won't see it again
# 3. Update the new keys everywhere they're used:# - CI/CD secrets# - ~/.aws/credentials# - Environment variables# - Application configuration
# 4. Test that new keys workaws sts get-caller-identity
# 5. Delete old access keysaws iam delete-access-key \ --access-key-id AKIA_OLD_KEY_ID \ --user-name your-username2.3.3 Wichtige AWS-Sicherheitsschritte
# Check CloudTrail for unauthorized activityaws cloudtrail lookup-events \ --lookup-attributes AttributeKey=Username,AttributeValue=your-username \ --max-items 100 \ --start-time 2025-11-20T00:00:00Z
# Review recent S3 bucket accessaws s3api get-bucket-logging --bucket your-bucket-name
# Check for unauthorized IAM changesaws iam get-credential-report2.3.4 GCP-Zugangsdaten
Für Google Cloud Platform:
# List service accountsgcloud iam service-accounts list
# Create new key for a service accountgcloud iam service-accounts keys create new-key.json \ --iam-account=sa-name@project-id.iam.gserviceaccount.com
# List all keys for a service accountgcloud iam service-accounts keys list \ --iam-account=sa-name@project-id.iam.gserviceaccount.com
# Delete old keysgcloud iam service-accounts keys delete KEY_ID \ --iam-account=sa-name@project-id.iam.gserviceaccount.com2.3.5 Azure-Zugangsdaten
Für Microsoft Azure:
# List service principalsaz ad sp list --show-mine
# Reset service principal credentialsaz ad sp credential reset \ --id <app-id> \ --append
# Create new client secretaz ad sp credential reset \ --id <app-id> \ --credential-description "New secret after Shai-Hulud"2.3.6 Datenbank-Zugangsdaten
Vergessen Sie nicht, Datenbank-Credentials zu rotieren:
# Example for PostgreSQL# Connect to your databasepsql -U admin -d postgres
# Create new user with same privilegesCREATE USER newuser WITH PASSWORD 'strong-new-password';GRANT ALL PRIVILEGES ON DATABASE yourdb TO newuser;
# Update application configuration# Test thoroughly# Then remove old userDROP USER olduser;2.3.7 Umgebungsvariablen und Secrets
Aktualisieren Sie alle Umgebungs-Secrets:
import crypto from 'crypto'
const generateSecureSecret = (length: number = 32): string => { return crypto.randomBytes(length).toString('hex')}
console.log('🔐 New secrets generated:\n')console.log(`SESSION_SECRET=${generateSecureSecret(64)}`)console.log(`API_SECRET=${generateSecureSecret(32)}`)console.log(`ENCRYPTION_KEY=${generateSecureSecret(32)}`)console.log(`JWT_SECRET=${generateSecureSecret(64)}`)console.log('\n⚠️ Update these in:')console.log(' - Vercel/Netlify/hosting platform')console.log(' - GitHub repository secrets')console.log(' - Local .env files')console.log(' - Team password manager')Nächste Schritte
Sie haben wichtige erste Schritte unternommen, um Ihr Astro-Projekt abzusichern. Der Schutz vor Supply-Chain-Angriffen erfordert jedoch dauerhafte Wachsamkeit und robuste Sicherheitspraktiken.
In Teil 2 geht es um langfristige Prävention (Dependency-Locking, Integritätsprüfungen, CI/CD-Härtung), Dependency-Isolation, Secret-Management, automatisierte Scans und Monitoring.
Fazit
Der Shai-Hulud-2.0-Angriff erinnert eindringlich daran, dass Supply-Chain-Sicherheit keine Option ist – sie ist ein kritischer Bestandteil moderner Webentwicklung. Die Sofortmaßnahmen in diesem Artikel sind nur die erste Verteidigungslinie.
Bei Fragen oder Anmerkungen erreichen Sie mich gerne auf Twitter.