
Lokaler statischer Sicherheitsscanner für Next.js-, Supabase- und Stripe-Apps: 24 AST-basierte Prüfungen auf geleakte Schlüssel, fehlende RLS und Grants, unsichere Webhooks. CLI und GitHub Action.
Kostenloser lokaler Sicherheitsscan für Next.js + Supabase + Stripe-Apps: geleakte Schlüssel, fehlende RLS und Grants, unsichere Stripe-Webhooks.
Dein KI-Agent hat die App ausgeliefert. Hat er auch deinen Stripe-Secret-Key ausgeliefert, eine Tabelle ohne RLS oder einen Webhook, den jeder aufrufen kann? Ein Befehl findet es heraus – lokal, in unter einer Sekunde.
npx github:edtrackai/nextjs-supabase-stripe-security-checker /path/to/your/app
Es ist noch nicht auf npm, daher führt npx es direkt aus diesem GitHub-Repo aus (benötigt Node 18+ und git).
- uses: edtrackai/nextjs-supabase-stripe-security-checker@v0
with:
fail-on: high
Der vollständige Workflow und die Berechtigungen sind unten und in docs/github-action.md beschrieben.
Supabase-RLS-Prüfer · Stripe-Webhook-Sicherheit · Next.js-Sicherheitsscan · Supabase Data API-Grants (42501)

git clone https://github.com/edtrackai/nextjs-supabase-stripe-security-checker.git
cd nextjs-supabase-stripe-security-checker && npm install
node bin/nss-security-check.js /path/to/your/app
Node 18 oder höher. Es gibt eine Abhängigkeit (@babel/parser). Es ist kostenlos und MIT-lizenziert, benötigt kein Konto, führt keine Netzwerkaufrufe durch und lädt niemals deinen Code hoch.
--fail-on=high beendet mit Exit-Code 1, und --json liefert maschinenlesbare Ausgabe.Anzeige (bezahlt, gleicher Autor): Willst du die Fixes? Launch Audit (12 $ zzgl. MwSt. wo anwendbar) fügt 28 Prüfungen hinzu, einen KI-Auditor-Agenten ohne Edit- oder Write-Tools sowie einen Datei:Zeile-Fixplan.
| Flag | Was es bewirkt |
|---|---|
--json | Maschinenlesbare Ausgabe: {tool, version, root, filesScanned, counts, findings[]} |
--fail-on=<sev> | Exit-Code 1, wenn ein Befund critical / high / medium / low oder höher ist (none schlägt nie fehl). Exit-Code 2 bei ungültigen Argumenten. |
--list | Gibt den Prüfkatalog aus |
--quiet | Lässt die einzeilige Fußzeile über die kostenpflichtigen Tools weg (wird nur auf einem Terminal nach stderr ausgegeben; ebenfalls deaktiviert mit NO_PROMO=1, CI oder GITHUB_ACTIONS) |
--help | Verwendung |
In CI: node path/to/bin/nss-security-check.js . --fail-on=high, oder verwende die GitHub Action (Job-Zusammenfassung, Anmerkungen, ein einziger angepinnter PR-Kommentar, nur GITHUB_TOKEN). Siehe den Beispiel-Workflow und die Berechtigungen in docs/github-action.md.
# .github/workflows/security-check.yml
name: Security check
on: [pull_request]
permissions:
contents: read
pull-requests: write # only for the PR comment; drop it with comment: false
jobs:
scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- uses: edtrackai/nextjs-supabase-stripe-security-checker@v0 # or pin @v0.5.0 / a commit SHA
with:
path: .
fail-on: high
Änderungen sind in CHANGELOG.md aufgeführt (0.5.0 fügt die Action hinzu).
| ID | Schweregrad | Bereich | Prüfung |
|---|---|---|---|
| K1 | kritisch | Schlüssel | Aktiver Stripe-Geheim-/eingeschränkter Schlüssel (sk_live_/rk_live_) im Quellcode, einschließlich mit + aufgeteilter Schlüssel (Nachweis wird redigiert) |
| K2 | kritisch | Schlüssel | Verdächtig wirkende NEXT_PUBLIC_-Variable (Service Role, Secret Key, Webhook Secret…) |
| K3 | kritisch | Schlüssel | .env-Datei mit von git verfolgten Werten |
| K4 | kritisch | Schlüssel | Server-Geheimnis oder Supabase-Admin-Client in einer "use client"-Komponente verwendet |
| A1 | hoch | Auth | auth.getSession() auf dem Server vertraut statt getUser()/getClaims() |
| A2 | hoch | Auth | Server Action schreibt Daten ohne Auth-Prüfung |
| A3 | hoch | Auth | API-Route (POST/PUT/PATCH/DELETE) schreibt Daten ohne Auth-Prüfung (Webhook-, Cron- und Auth-Routen ausgenommen) |
| A4 | hoch | Auth | Admin-Client mit einer aus der Anfrage stammenden ID ohne Eigentümerfilter abgefragt (IDOR) |
| A5 | mittel | Auth | Offene Weiterleitung aus einem Query-Parameter |
| R1 | kritisch | RLS | Tabelle ohne Row Level Security erstellt |
| R2 | kritisch | RLS | Schreibrichtlinie mit using (true) / with check (true) |
| R3 | hoch | RLS | Richtlinie, die der Rolle anon das Schreiben erlaubt |
| R4 | hoch | RLS | security definer-Funktion ohne festen search_path |
| R5 | mittel | RLS | Tabelle in public ohne explizites GRANT. Supabase kündigte an, die Standard-Grants für neue öffentliche Tabellen ab dem 30. Okt. 2026 einzustellen, doch Ende August schrieb ein Maintainer der Supabase CLI (supabase/cli PR #6337), dass die frühere Standardänderung „nie umgesetzt wurde" und gehostete Projekte weiterhin automatisch Grants vergaben, sodass sich das Datum verschieben kann: Prüfe, was dein eigenes Projekt tut. Ohne Grant gibt die Data API 42501 zurück |
| R6 | hoch | RLS | Pauschales grant ... on all tables in schema public / alter default privileges ... grant an anon/authenticated (der schnelle 42501-Fix, der auch Tabellen ohne RLS offenlegt) |
| S1 | kritisch | Stripe | Webhook ohne Signaturprüfung (constructEvent) |
| S2 | kritisch | Stripe | Webhook parst request.json() statt des Roh-Bodys |
| S3 | mittel | Stripe | Webhook hat keine Idempotenz auf event.id |
| S4 | hoch | Stripe | Checkout-Preis oder -Betrag aus der Anfrage übernommen |
| S5 | hoch | Stripe | Zugriff auf der Checkout-Erfolgsseite gewährt statt im Webhook |
| S6 | mittel | Stripe | Webhook-Deduplizierung, die ein fehlgeschlagenes Ereignis verschlucken kann: Duplikate ohne pending/completed-Status übersprungen |
| S7 | niedrig | Stripe | Abrechnungszeitraum aus items.data[0] gelesen (falsch für Abonnements mit mehreren Positionen seit API 2025-03-31.basil) |
| H1 | mittel | Härtung | Keine Sicherheits-Header in next.config |
| H2 | mittel | Härtung | dangerouslySetInnerHTML mit einem Nicht-Literal-Wert |
fixtures/vulnerable-app löst alle 23 dateibasierten Prüfungen aus, und die Tests prüfen jede einzelne in der erwarteten Datei. K3 wird in einem temporären Git-Repo getestet.fixtures/clean-app (eine gehärtete Referenz-App) und fixtures/near-miss (sicherer Code, der wie jeder Fehler aussieht: Roh-Body-Webhooks mit pending/completed-Idempotenz, Multi-Item-sichere Zeitraumssuche, abgesicherte Weiterleitungen, eigentümergefilterte Admin-Abfragen, select using (true), JSON-LD) müssen 0 Befunde erzeugen.npm test führt die node:test-Suite aus, einschließlich der CLI-Flags und Exit-Codes. npm run smoke liefert eine einzeilige Zusammenfassung.