SaaS Security Checklist
Sicherheits-Checklist speziell fuer SaaS-Anwendungen mit Next.js, Supabase und Stripe. Jedes Finding referenziert das Repo, in dem das Anti-Pattern gefunden wurde.
Abgrenzung zum security-scanner Skill: Der security-scanner deckt allgemeine OWASP Top 10 ab. Dieser Skill ist SaaS-spezifisch: Subscription-Autorisierung, Payment-Webhook-Security, Supabase-RLS, Multi-Tenant-Isolation. Fuer vollstaendige Abdeckung BEIDE Skills zusammen verwenden.
Scoring Rubric
Nach Durchlauf der Checklist, Score berechnen:
| Score |
Rating |
Bedeutung |
| 0-40% |
CRITICAL |
Sofortige Sicherheitsprobleme. NICHT deployen. |
| 40-70% |
NEEDS WORK |
Signifikante Luecken. Vor Production fixen. |
| 70-90% |
SOLID |
Gute Basis. Kleinere Verbesserungen noetig. |
| 90-100% |
HARDENED |
Production-ready Security Posture. |
1. Authentication Layer
Kritische Findings aus Repo-Analyse
| Finding |
Schwere |
Gefunden in |
| Kein Middleware-basierter Route-Schutz, nur Layout-Redirects |
KRITISCH |
Saas-Kit-supabase |
| Password-Feld als type="text" (Klartext sichtbar) |
HOCH |
Saas-Kit-supabase |
| Hardcodiertes JWT Secret ("your-secret-key") |
KRITISCH |
intelligent-rag-service |
| Dummy-Authentifizierung (user/password) |
KRITISCH |
intelligent-rag-service |
| python-jose (unmaintained seit 2023) |
HOCH |
scalable-rag-pipeline |
| Deprecated @supabase/auth-helpers-nextjs |
HOCH |
Saas-Kit-supabase |
Checklist
2. Row Level Security (Supabase)
Kritische Findings
| Finding |
Schwere |
Gefunden in |
| KEIN RLS auf profiles und subscriptions |
KRITISCH |
Saas-Kit-supabase |
| anon-Rolle hat unnoetige Rechte auf todo_list |
MITTEL |
supabase-nextjs-template |
| CREATE TRIGGER fuer Profil-Erstellung fehlt in Migration |
HOCH |
Saas-Kit-supabase |
Checklist
3. Payment Security (Stripe)
Checklist
4. Secrets Management
Kritische Findings
| Finding |
Schwere |
Gefunden in |
| AWS Account ID (038462775601) hardcoded in Code und CI |
KRITISCH |
intelligent-rag-service |
| IAM Role ARN hardcoded in Kubernetes-Manifesten |
KRITISCH |
intelligent-rag-service |
| JWT Secret als "your-secret-key" im Code |
KRITISCH |
intelligent-rag-service |
| Default-Secrets in Config-Dateien |
HOCH |
scalable-rag-pipeline |
Checklist
5. HTTP Security Headers
Findings
| Finding |
Schwere |
Gefunden in |
| Kein CSRF-Schutz |
MITTEL |
Saas-Kit-supabase |
| Keine CSP-Headers |
MITTEL |
Saas-Kit-supabase |
| Kein Rate Limiting |
MITTEL |
Saas-Kit-supabase |
Checklist
Next.js Header-Konfiguration
// next.config.ts
const securityHeaders = [
{ key: "X-Content-Type-Options", value: "nosniff" },
{ key: "X-Frame-Options", value: "DENY" },
{ key: "X-XSS-Protection", value: "1; mode=block" },
{ key: "Referrer-Policy", value: "strict-origin-when-cross-origin" },
{ key: "Permissions-Policy", value: "camera=(), microphone=(), geolocation=()" },
{
key: "Content-Security-Policy",
value: "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self' data:; connect-src 'self' https://*.supabase.co wss://*.supabase.co https://api.stripe.com;",
},
];
6. Input Validation
Checklist
7. Dependency Security
Findings
| Finding |
Schwere |
Gefunden in |
| Deprecated @supabase/auth-helpers-nextjs |
HOCH |
Saas-Kit-supabase |
| python-jose unmaintained |
HOCH |
scalable-rag-pipeline |
| Anthropic SDK 0.8.0 extrem veraltet |
MITTEL |
scalable-rag-pipeline |
| python-jose fehlt in requirements.txt |
HOCH |
intelligent-rag-service |
| TypeScript strict: false |
HOCH |
Saas-Kit-supabase |
Checklist
8. DSGVO/GDPR Compliance
Findings
| Finding |
Schwere |
Gefunden in |
| Vercel Analytics + Google Tag Manager eingebaut |
MITTEL |
supabase-nextjs-template |
| PostHog-Telemetrie standardmaessig aktiv |
MITTEL |
n8n |
| console.log ueberall (potentiell PII) |
MITTEL |
Saas-Kit-supabase |
Checklist
9. Logging & Monitoring
Findings
| Finding |
Schwere |
Gefunden in |
| console.log ueberall in Production |
MITTEL |
Saas-Kit-supabase |
| print() statt Logging-Framework |
MITTEL |
intelligent-rag-service |
| print() in API main.py |
MITTEL |
scalable-rag-pipeline |
| Observability definiert aber nicht aufgerufen |
MITTEL |
scalable-rag-pipeline |
Checklist
10. Frontend Security
Checklist
11. Infrastructure Security
Checklist
12. Multi-Tenancy Security (wenn zutreffend)
Checklist
Quick Audit Command
Fuer eine schnelle erste Einschaetzung:
# 1. Check for hardcoded secrets
grep -rn "sk_live\|sk_test\|whsec_\|secret.*=.*['\"]" --include="*.ts" --include="*.tsx" --include="*.py" src/ app/ api/
# 2. Check for console.log in production code
grep -rn "console\.log\|console\.error" --include="*.ts" --include="*.tsx" src/ app/ | grep -v "node_modules" | grep -v ".test."
# 3. Check for missing RLS
# In Supabase SQL Editor:
SELECT tablename FROM pg_tables WHERE schemaname = 'public' AND NOT rowsecurity;
# 4. Check for deprecated packages
npm ls @supabase/auth-helpers-nextjs 2>/dev/null && echo "DEPRECATED: auth-helpers found"
pip list 2>/dev/null | grep python-jose && echo "DEPRECATED: python-jose found"
# 5. Check TypeScript strict mode
grep '"strict"' tsconfig.json
# 6. Check for type="text" on password fields
grep -rn 'type="text"' --include="*.tsx" src/ app/ | grep -i pass
Output Format
Nach der Audit, fasse so zusammen:
## SaaS Security Audit
**Score:** X/100 (RATING)
**Datum:** YYYY-MM-DD
### Kritische Findings (sofort fixen)
1. [Finding + Repo-Referenz]
2. ...
### Hohe Findings (vor Production fixen)
1. [Finding]
2. ...
### Mittlere Findings (nach Launch fixen)
1. [Finding]
2. ...
### Positiv (bereits gut)
1. [Was bereits richtig gemacht wird]
2. ...
### Empfohlene Reihenfolge
1. [Wichtigstes Fix zuerst]
2. ...
1---2name: saas-security-checklist3description: Security checklist specifically for SaaS applications built with Next.js, Supabase, and Stripe. Covers authentication hardening, Row Level Security, Stripe webhook verification, secrets management, CSRF/CSP/CORS headers, input validation, rate limiting, DSGVO/GDPR compliance, and common anti-patterns found in real SaaS templates. Triggers on: SaaS security, Supabase security, Stripe security, SaaS checklist, secure SaaS, harden SaaS, SaaS audit, Next.js security, Supabase RLS audit, payment security, or any security review of a SaaS application.4---5
6# SaaS Security Checklist
7
8Sicherheits-Checklist speziell fuer SaaS-Anwendungen mit Next.js, Supabase und Stripe. Jedes Finding referenziert das Repo, in dem das Anti-Pattern gefunden wurde.
9
10**Abgrenzung zum security-scanner Skill:** Der `security-scanner` deckt allgemeine OWASP Top 10 ab. Dieser Skill ist SaaS-spezifisch: Subscription-Autorisierung, Payment-Webhook-Security, Supabase-RLS, Multi-Tenant-Isolation. Fuer vollstaendige Abdeckung BEIDE Skills zusammen verwenden.
11
12---
13
14## Scoring Rubric
15
16Nach Durchlauf der Checklist, Score berechnen:
17
18| Score | Rating | Bedeutung |
19|-------|--------|-----------|
20| 0-40% | **CRITICAL** | Sofortige Sicherheitsprobleme. NICHT deployen. |
21| 40-70% | **NEEDS WORK** | Signifikante Luecken. Vor Production fixen. |
22| 70-90% | **SOLID** | Gute Basis. Kleinere Verbesserungen noetig. |
23| 90-100% | **HARDENED** | Production-ready Security Posture. |
24
25---
26
27## 1. Authentication Layer
28
29### Kritische Findings aus Repo-Analyse
30
31| Finding | Schwere | Gefunden in |
32|---------|---------|-------------|
33| Kein Middleware-basierter Route-Schutz, nur Layout-Redirects | KRITISCH | Saas-Kit-supabase |
34| Password-Feld als type="text" (Klartext sichtbar) | HOCH | Saas-Kit-supabase |
35| Hardcodiertes JWT Secret ("your-secret-key") | KRITISCH | intelligent-rag-service |
36| Dummy-Authentifizierung (user/password) | KRITISCH | intelligent-rag-service |
37| python-jose (unmaintained seit 2023) | HOCH | scalable-rag-pipeline |
38| Deprecated @supabase/auth-helpers-nextjs | HOCH | Saas-Kit-supabase |
39
40### Checklist
41
42- [ ] @supabase/ssr verwendet (NICHT deprecated @supabase/auth-helpers-nextjs)
43- [ ] Middleware-basierter Route-Schutz (NICHT nur Layout-Level-Redirects)
44- [ ] `getUser()` statt `getSession()` fuer Server-seitige Validierung
45- [ ] Alle Password-Felder als type="password"
46- [ ] JWT Secrets aus Environment-Variablen (NIEMALS hardcoded)
47- [ ] Maintained JWT Library (PyJWT oder joserfc, NICHT python-jose)
48- [ ] Session Cookies: HttpOnly, Secure, SameSite=Lax
49- [ ] OAuth State-Parameter validiert im Callback
50- [ ] MFA-Support mindestens fuer Admin-Accounts
51- [ ] Account-Lockout nach N fehlgeschlagenen Versuchen
52- [ ] Sicherer Password-Reset-Flow (zeitlich limitierte Tokens)
53- [ ] Rate Limiting auf Auth-Endpoints
54
55---
56
57## 2. Row Level Security (Supabase)
58
59### Kritische Findings
60
61| Finding | Schwere | Gefunden in |
62|---------|---------|-------------|
63| KEIN RLS auf profiles und subscriptions | KRITISCH | Saas-Kit-supabase |
64| anon-Rolle hat unnoetige Rechte auf todo_list | MITTEL | supabase-nextjs-template |
65| CREATE TRIGGER fuer Profil-Erstellung fehlt in Migration | HOCH | Saas-Kit-supabase |
66
67### Checklist
68
69- [ ] RLS AKTIVIERT auf JEDER Tabelle mit User-Daten
70- [ ] SELECT Policies: User kann nur eigene Daten lesen
71- [ ] INSERT Policies: user_id wird aus auth.uid() gesetzt, nicht vom Client
72- [ ] UPDATE Policies: User kann nur eigene Records aendern
73- [ ] DELETE Policies: User kann nur eigene Records loeschen
74- [ ] Service Role NUR in server-seitigem Code (Webhooks, Server Actions)
75- [ ] anon-Rolle hat MINIMALE Permissions
76- [ ] Kein RLS-Bypass via direkten Tabellenzugriff
77- [ ] RLS-Policies getestet: Versuch, fremde Daten zu lesen
78- [ ] Trigger-Functions nutzen SECURITY DEFINER mit explizitem search_path
79- [ ] CREATE TRIGGER Statement in Migrations vorhanden
80- [ ] Storage-Buckets mit user-spezifischen Pfaden und RLS
81
82---
83
84## 3. Payment Security (Stripe)
85
86### Checklist
87
88- [ ] STRIPE_SECRET_KEY nur server-side (KEIN NEXT_PUBLIC_ Prefix)
89- [ ] Webhook-Signatur auf JEDEM Event verifiziert (constructEvent)
90- [ ] Webhook-Endpoint nutzt Raw Body (nicht JSON-parsed) fuer Signatur
91- [ ] Idempotente Webhook-Verarbeitung (Event-ID pruefen)
92- [ ] Subscription-Status server-side geprueft (nicht client-side)
93- [ ] Price IDs gegen erlaubte Liste validiert
94- [ ] Customer Portal Session server-side erstellt mit authentifiziertem User
95- [ ] Keine Subscription-Daten in localStorage oder Client-State
96- [ ] Grace Period bei Payment Failure (nicht sofort sperren)
97- [ ] Stripe CLI fuer lokales Webhook-Testing konfiguriert
98- [ ] SUPABASE_SERVICE_ROLE_KEY nur in Webhook-Handler, nie im Client
99
100---
101
102## 4. Secrets Management
103
104### Kritische Findings
105
106| Finding | Schwere | Gefunden in |
107|---------|---------|-------------|
108| AWS Account ID (038462775601) hardcoded in Code und CI | KRITISCH | intelligent-rag-service |
109| IAM Role ARN hardcoded in Kubernetes-Manifesten | KRITISCH | intelligent-rag-service |
110| JWT Secret als "your-secret-key" im Code | KRITISCH | intelligent-rag-service |
111| Default-Secrets in Config-Dateien | HOCH | scalable-rag-pipeline |
112
113### Checklist
114
115- [ ] Alle Secrets in Environment-Variablen (NIEMALS im Code)
116- [ ] .env Dateien in .gitignore
117- [ ] .env.example mit Placeholder-Werten (nie echte Secrets)
118- [ ] Keine AWS Account IDs, ARNs oder API Keys in Code oder CI-Manifesten
119- [ ] Production-Secrets in AWS Secrets Manager / Vault / Supabase Vault
120- [ ] Secret-Rotation bei Verdacht auf Exposure
121- [ ] Git-History clean (git-filter-repo wenn noetig)
122- [ ] CI/CD nutzt GitHub Secrets oder Equivalent
123- [ ] Keine Secrets in Docker-Images oder Build-Logs
124- [ ] SUPABASE_SERVICE_ROLE_KEY nicht in Client-bundles
125
126---
127
128## 5. HTTP Security Headers
129
130### Findings
131
132| Finding | Schwere | Gefunden in |
133|---------|---------|-------------|
134| Kein CSRF-Schutz | MITTEL | Saas-Kit-supabase |
135| Keine CSP-Headers | MITTEL | Saas-Kit-supabase |
136| Kein Rate Limiting | MITTEL | Saas-Kit-supabase |
137
138### Checklist
139
140- [ ] Content-Security-Policy Header konfiguriert
141- [ ] X-Content-Type-Options: nosniff
142- [ ] X-Frame-Options: DENY (oder CSP frame-ancestors)
143- [ ] Strict-Transport-Security (HSTS)
144- [ ] Referrer-Policy: strict-origin-when-cross-origin
145- [ ] Permissions-Policy: Camera, Microphone, Geolocation einschraenken
146- [ ] CORS: Explizite Origins, KEIN Wildcard * in Production
147- [ ] CSRF-Schutz auf allen state-mutierenden Endpoints
148
149### Next.js Header-Konfiguration
150
151```typescript
152// next.config.ts
153const securityHeaders = [
154 { key: "X-Content-Type-Options", value: "nosniff" },
155 { key: "X-Frame-Options", value: "DENY" },
156 { key: "X-XSS-Protection", value: "1; mode=block" },
157 { key: "Referrer-Policy", value: "strict-origin-when-cross-origin" },
158 { key: "Permissions-Policy", value: "camera=(), microphone=(), geolocation=()" },
159 {
160 key: "Content-Security-Policy",
161 value: "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self' data:; connect-src 'self' https://*.supabase.co wss://*.supabase.co https://api.stripe.com;",
162 },
163];
164```
165
166---
167
168## 6. Input Validation
169
170### Checklist
171
172- [ ] Alle API-Inputs validiert mit Zod (Frontend) + Pydantic (Backend)
173- [ ] File-Uploads: Typ, Groesse, Inhalt validiert (nicht nur Extension)
174- [ ] SQL: ORM oder parametrisierte Queries (NIEMALS String-Concatenation)
175- [ ] Kein eval(), kein dangerouslySetInnerHTML ohne Sanitization
176- [ ] Rate Limiting auf oeffentlichen Endpoints (Auth, API, Webhooks)
177- [ ] Request-Size-Limits konfiguriert
178- [ ] User-generierter Content escaped vor Rendering
179- [ ] Redirect-URLs validiert (keine Open Redirects)
180
181---
182
183## 7. Dependency Security
184
185### Findings
186
187| Finding | Schwere | Gefunden in |
188|---------|---------|-------------|
189| Deprecated @supabase/auth-helpers-nextjs | HOCH | Saas-Kit-supabase |
190| python-jose unmaintained | HOCH | scalable-rag-pipeline |
191| Anthropic SDK 0.8.0 extrem veraltet | MITTEL | scalable-rag-pipeline |
192| python-jose fehlt in requirements.txt | HOCH | intelligent-rag-service |
193| TypeScript strict: false | HOCH | Saas-Kit-supabase |
194
195### Checklist
196
197- [ ] Keine deprecated Libraries (@supabase/auth-helpers, python-jose, vm2)
198- [ ] Keine unmaintained Libraries (letztes Update >2 Jahre)
199- [ ] Dependabot oder Renovate konfiguriert
200- [ ] Lock Files committed (package-lock.json / pnpm-lock.yaml / poetry.lock)
201- [ ] TypeScript strict: true
202- [ ] Alle Dependencies in package.json/requirements.txt gelistet
203- [ ] `npm audit` / `pip-audit` zeigt keine Critical/High Findings
204- [ ] Keine bekannten CVEs in direkten Dependencies
205
206---
207
208## 8. DSGVO/GDPR Compliance
209
210### Findings
211
212| Finding | Schwere | Gefunden in |
213|---------|---------|-------------|
214| Vercel Analytics + Google Tag Manager eingebaut | MITTEL | supabase-nextjs-template |
215| PostHog-Telemetrie standardmaessig aktiv | MITTEL | n8n |
216| console.log ueberall (potentiell PII) | MITTEL | Saas-Kit-supabase |
217
218### Checklist
219
220- [ ] Cookie-Consent-Banner VOR jeglichem Tracking
221- [ ] Analytics nur nach Consent geladen
222- [ ] Kein PII in Logs (Namen, Emails, IPs) -- structlog/Pino, NICHT console.log
223- [ ] Daten-Export-Endpoint fuer User (DSGVO Art. 20)
224- [ ] Account-Loeschung-Endpoint (DSGVO Art. 17 -- Recht auf Vergessen)
225- [ ] Privacy Policy und Terms of Service Seiten vorhanden
226- [ ] Auftragsverarbeitungsvertrag mit allen Sub-Prozessoren
227- [ ] Server-Standort dokumentiert (EU bevorzugt fuer EU-Kunden)
228- [ ] Supabase-Projekt in EU-Region wenn EU-Kunden bedient werden
229- [ ] Keine PII an Drittanbieter ohne Consent
230
231---
232
233## 9. Logging & Monitoring
234
235### Findings
236
237| Finding | Schwere | Gefunden in |
238|---------|---------|-------------|
239| console.log ueberall in Production | MITTEL | Saas-Kit-supabase |
240| print() statt Logging-Framework | MITTEL | intelligent-rag-service |
241| print() in API main.py | MITTEL | scalable-rag-pipeline |
242| Observability definiert aber nicht aufgerufen | MITTEL | scalable-rag-pipeline |
243
244### Checklist
245
246- [ ] Kein console.log/print() in Production-Code
247- [ ] Structured Logging (structlog fuer Python, Pino fuer Node.js)
248- [ ] Kein PII in Log-Output
249- [ ] Auth-Events geloggt (Login, Logout, Failed Attempts, Password Reset)
250- [ ] Payment-Events geloggt (Subscription Changes, Webhook Failures)
251- [ ] Error Tracking (Sentry) mit PII Scrubbing aktiviert
252- [ ] Alerting fuer: Auth-Anomalien, Webhook-Failures, Subscription-Fehler
253- [ ] Observability tatsaechlich eingebunden (nicht nur definiert)
254
255---
256
257## 10. Frontend Security
258
259### Checklist
260
261- [ ] Kein dangerouslySetInnerHTML ohne DOMPurify Sanitization
262- [ ] Keine sensitiven Daten in localStorage (Tokens, PII)
263- [ ] API Keys mit NEXT_PUBLIC_ Prefix sind wirklich public-safe
264- [ ] STRIPE_SECRET_KEY hat KEINEN NEXT_PUBLIC_ Prefix
265- [ ] Error Messages leaken keine internen Details
266- [ ] Source Maps deaktiviert in Production
267- [ ] Keine Credentials in Frontend-Bundles
268- [ ] Image-Quellen via next/image mit allowedDomains
269
270---
271
272## 11. Infrastructure Security
273
274### Checklist
275
276- [ ] HTTPS everywhere (kein HTTP in Production)
277- [ ] Environment-spezifische Konfiguration (dev/staging/prod)
278- [ ] Kein Debug Mode in Production
279- [ ] Datenbank-Verbindung verschluesselt (SSL)
280- [ ] Backup-Strategie fuer Datenbank
281- [ ] Incident Response Plan dokumentiert
282- [ ] Deployment via CI/CD (kein manuelles Deployment)
283- [ ] Keine Default-Credentials in Production
284
285---
286
287## 12. Multi-Tenancy Security (wenn zutreffend)
288
289### Checklist
290
291- [ ] Tenant-Isolation auf Datenbank-Ebene (RLS mit Org-ID)
292- [ ] Kein Cross-Tenant Data Leakage
293- [ ] Tenant-ID in jedem Query validiert
294- [ ] Admin-Aktionen auf eigenen Tenant beschraenkt
295- [ ] Invite-System validiert Email-Domain (wenn gewuenscht)
296- [ ] Tenant-Wechsel invalidiert Cache
297
298---
299
300## Quick Audit Command
301
302Fuer eine schnelle erste Einschaetzung:
303
304```bash
305# 1. Check for hardcoded secrets
306grep -rn "sk_live\|sk_test\|whsec_\|secret.*=.*['\"]" --include="*.ts" --include="*.tsx" --include="*.py" src/ app/ api/
307
308# 2. Check for console.log in production code
309grep -rn "console\.log\|console\.error" --include="*.ts" --include="*.tsx" src/ app/ | grep -v "node_modules" | grep -v ".test."
310
311# 3. Check for missing RLS
312# In Supabase SQL Editor:
313SELECT tablename FROM pg_tables WHERE schemaname = 'public' AND NOT rowsecurity;
314
315# 4. Check for deprecated packages
316npm ls @supabase/auth-helpers-nextjs 2>/dev/null && echo "DEPRECATED: auth-helpers found"
317pip list 2>/dev/null | grep python-jose && echo "DEPRECATED: python-jose found"
318
319# 5. Check TypeScript strict mode
320grep '"strict"' tsconfig.json
321
322# 6. Check for type="text" on password fields
323grep -rn 'type="text"' --include="*.tsx" src/ app/ | grep -i pass
324```
325
326---
327
328## Output Format
329
330Nach der Audit, fasse so zusammen:
331
332```
333## SaaS Security Audit
334
335**Score:** X/100 (RATING)
336**Datum:** YYYY-MM-DD
337
338### Kritische Findings (sofort fixen)
3391. [Finding + Repo-Referenz]
3402. ...
341
342### Hohe Findings (vor Production fixen)
3431. [Finding]
3442. ...
345
346### Mittlere Findings (nach Launch fixen)
3471. [Finding]
3482. ...
349
350### Positiv (bereits gut)
3511. [Was bereits richtig gemacht wird]
3522. ...
353
354### Empfohlene Reihenfolge
3551. [Wichtigstes Fix zuerst]
3562. ...
357```