Schnell zu launchen ist in Ordnung, aber es gibt eine kurze Liste, die du durchgehen solltest, bevor du deine App für die Welt öffnest. Nichts davon erfordert Sicherheitsexpertise, und alles lässt sich in ein paar Minuten von außen prüfen. Dieser Guide behandelt jeden Punkt in drei Teilen: warum er wichtig ist, wie du ihn selbst prüfst und wie du ihn behebst, mit Konfigurationsbeispielen für die Stacks, die KI-gebaute Apps am häufigsten nutzen (Next.js auf Vercel, Supabase, Firebase). Am Ende bekommst du die Zwei-Minuten-Version für deine Launch-Liste.
Wie Angreifer das in Minuten finden
Die meisten Einbrüche in KI-gebaute Apps sind keine cleveren Hacks. Jemand öffnet deine Website, drückt F12, liest das JavaScript, das deine App bereits an seinen Browser geschickt hat, und kopiert eine URL, die deine App ohnehin aufruft. Automatische Scanner tun dasselbe im großen Stil und klopfen an gängige Pfade wie /.env oder /.git auf tausenden Websites pro Tag, ohne überhaupt zu wissen, dass es dich gibt. Alles Folgende können sie ohne jeden Zugriff auf deinen Code prüfen, und genau deshalb solltest du es zuerst prüfen.
1. Keine Secrets im Frontend
Warum es wichtig ist. API-Keys und Tokens gehören ausschließlich auf den Server. Wenn ein KI-Assistent einen Dienst „verbindet", legt er den Key oft direkt im Client-Code ab, wo ihn jeder in den DevTools lesen kann. Ein geleakter Stripe-sk_live_-Key kann echtes Geld bewegen; ein Supabase-service_role-Key liefert deine gesamte Datenbank aus; ein OpenAI- oder Anthropic-Key lässt dich die Rechnung von jemand anderem zahlen.
So prüfst du es. Öffne deine Website, drücke F12 → Tab Sources (oder Network nach JS gefiltert) und durchsuche die Dateien nach Strings wie sk_live, service_role, AKIA, sk-ant, AIza oder -----BEGIN. Nutzt dein Framework Variablen mit öffentlichem Präfix (NEXT_PUBLIC_, VITE_, NUXT_PUBLIC_), stell sicher, dass keine davon ein Secret enthält: Dieses Präfix bedeutet wörtlich „das geht in den Browser".
So behebst du es. Verschiebe jedes Secret in eine Server-Umgebungsvariable und mach den Aufruf aus einer API-Route oder Serverless-Funktion; der Browser spricht mit deinem Server, nie mit dem Anbieter. Und rotiere den geleakten Key: War er einmal in einem öffentlichen Bundle, gilt er als kompromittiert, auch nachdem du ihn entfernt hast. Mehr dazu in den Secrets, die deine App im Browser preisgibt.
2. HTTPS und Sicherheits-Header
Warum es wichtig ist. Liefere alles über HTTPS aus und leite HTTP dorthin um, damit niemand den Traffic mitlesen oder manipulieren kann. Füge dann die Header hinzu, mit denen Browser deine Nutzer verteidigen: Content-Security-Policy gegen Injection, Strict-Transport-Security zum Festnageln von HTTPS, X-Frame-Options gegen Clickjacking und X-Content-Type-Options, damit der Browser Dateitypen nicht „errät". Die meisten generierten Apps kommen standardmäßig ohne jeden davon.
So prüfst du es. Fordere deine Website mit curl -I https://deinedomain.de an und sieh dir die zurückkommenden Header an, oder nutze den kostenlosen Security-Header-Checker.
So behebst du es. In Next.js deklarierst du sie in next.config.js; auf Vercel, für jedes Framework, in vercel.json:
{
"headers": [
{
"source": "/(.*)",
"headers": [
{ "key": "Strict-Transport-Security", "value": "max-age=31536000; includeSubDomains" },
{ "key": "X-Frame-Options", "value": "SAMEORIGIN" },
{ "key": "X-Content-Type-Options", "value": "nosniff" },
{ "key": "Referrer-Policy", "value": "strict-origin-when-cross-origin" },
{ "key": "Permissions-Policy", "value": "camera=(), microphone=(), geolocation=()" }
]
}
]
}
Die CSP verdient einen eigenen Moment: Starte im Modus Content-Security-Policy-Report-Only, sieh, was sie blockieren würde, und schalte sie scharf, sobald sie nichts mehr kaputt macht. Siehe HTTP-Sicherheits-Header erklärt.
3. Datenbankregeln (RLS) auf jeder Tabelle
Warum es wichtig ist. Nutzt du Supabase oder Firebase, spricht deine App direkt aus dem Browser mit der Datenbank; die Datenbankregeln sind also das Einzige, was zwischen einem Besucher und deinen Daten steht. Ohne sie liest und beschreibt jeder mit dem öffentlichen Key deine Tabellen ohne Login: genau die Lücke hinter der RLS-Schwachstelle von Lovable.
So prüfst du es. Kopiere bei geöffneter App einen /rest/v1/-Aufruf aus dem Tab Network und öffne ihn in einem Inkognito-Fenster. Liefert er ohne Session Daten, bist du exponiert. In Supabase markiert der Table Editor Tabellen mit einem roten „RLS disabled"-Badge. In Firebase prüfe, dass die Regeln nicht noch im Testmodus sind (allow read, write: if true oder mit Ablaufdatum).
So behebst du es. Aktiviere Row-Level Security auf jeder Tabelle mit einer Deny-by-default-Policy und schreib Regeln pro Operation, die an den Nutzer gebunden sind. In Supabase das Minimum für eine Tabelle mit einer Spalte user_id:
alter table public.items enable row level security;
create policy "items: nur eigene Zeilen" on public.items
for all to authenticated
using ((select auth.uid()) = user_id)
with check ((select auth.uid()) = user_id);
Und verlass dich nie darauf, einen Button in der UI zu verstecken: Die Anfrage existiert trotzdem.
4. Keine exponierten sensiblen Dateien
Warum es wichtig ist. Eine einzige Anfrage an /.env kann jedes Secret ausliefern, das deine App nutzt; /.git/config lässt jeden dein ganzes Repository herunterladen; veröffentlichte Source Maps erlauben es, deinen Originalcode zu rekonstruieren; ein vergessenes backup.sql ist deine Datenbank in einer Datei.
So prüfst du es. Probiere deinedomain.de/.env, /.git/HEAD, /.DS_Store, /backup.sql im Browser und öffne eine JS-Datei aus deinem Bundle, um zu sehen, ob sie mit einer Zeile //# sourceMappingURL= endet, die auf eine erreichbare .map zeigt. Auf Plattformen wie Vercel oder Netlify wird die .env nie deployt, aber auf einem VPS mit nginx oder Apache passiert es.
So behebst du es. Blockiere Dotfiles auf dem Server (in nginx location ~ /\. { deny all; }), deaktiviere Source Maps in der Produktion (productionBrowserSourceMaps: false in Next.js, build.sourcemap: false in Vite) und nimm Backups aus dem öffentlichen Ordner.
5. CORS dichtgemacht
Warum es wichtig ist. Eine CORS-Richtlinie, die jede Herkunft mit Credentials spiegelt, erlaubt einer bösartigen Website, die Daten deiner Nutzer mit deren Session zu lesen. Access-Control-Allow-Origin: * ohne Credentials ist für öffentliche Daten harmlos; gefährlich ist, jede anfragende Herkunft zurückzuspiegeln und Access-Control-Allow-Credentials: true hinzuzufügen.
So prüfst du es. Fordere einen deiner API-Endpoints mit curl -I -H "Origin: https://evil.example" https://deinedomain.de/api/irgendwas an. Liefert die Antwort dieselbe Herkunft in Access-Control-Allow-Origin plus Allow-Credentials: true, hast du das Problem.
So behebst du es. Führe eine geschlossene Liste erlaubter Herkünfte (deine Produktionsdomains und höchstens die Preview-Domain) und vergleiche dagegen; jede andere Herkunft bekommt keinen Header.
6. Cookies und Sessions richtig konfiguriert
Warum es wichtig ist. Session-Cookies sollten Secure (nur HTTPS), HttpOnly (aus JavaScript nicht lesbar, damit ein XSS sie nicht stehlen kann) und SameSite=Lax oder Strict (schützt vor CSRF) tragen. Das ist eine Zeile Konfiguration und schließt eine ganze Klasse von Account-Takeover-Bugs.
So prüfst du es. F12 → Application → Cookies und sieh dir die Spalten Secure, HttpOnly und SameSite deines Session-Cookies an. Nutzt du einen Auth-Anbieter (Supabase Auth, Clerk, NextAuth), sind sie meist korrekt; durchfallen tun die Cookies, die deine eigene App setzt.
So behebst du es. Beim Setzen des Cookies: Set-Cookie: session=…; Secure; HttpOnly; SameSite=Lax; Path=/. In Express: res.cookie(name, value, { secure: true, httpOnly: true, sameSite: 'lax' }).
7. Abhängigkeiten mit bekannten Schwachstellen
Warum es wichtig ist. Deine App schleppt hunderte Pakete mit. Eine verwundbare Version einer Bibliothek, die Nutzereingaben parst, ist ein Einstiegspunkt, den du nicht geschrieben hast, der aber trotzdem deiner ist.
So prüfst und behebst du es. Führe npm audit im Projekt aus und löse zuerst kritische und hohe Funde; aktiviere Dependabot oder Renovate im Repository, damit Patches zu dir kommen. Wenn deine Website eine öffentliche package.json exponiert, verrätst du außerdem deine Versionen.
8. Rate Limits auf Endpoints, die Geld kosten oder Türen öffnen
Warum es wichtig ist. Das Login-Formular, die Registrierung, der E-Mail-Versand und jeder Endpoint, der eine kostenpflichtige KI-API aufruft, brauchen ein Limit pro IP oder pro Konto. Ohne das probiert ein Skript tausende Passwörter durch oder treibt über Nacht eine Token-Rechnung in die Höhe.
So behebst du es. Ein einfaches serverseitiges Rate Limit (pro IP und Minute) und bei kostenpflichtigen Anbietern eine Ausgabenobergrenze in deren Dashboard. Auth-Anbieter liefern Versuchslimits meist schon aktiv mit: Prüfe, dass du sie nicht deaktiviert hast.
9. Fehler, die nicht zu viel verraten
Warum es wichtig ist. Eine Fehlerseite mit vollem Stack Trace, der SQL-Abfrage oder dem Serverpfad ist eine Landkarte für den Angreifer. Dasselbe gilt für Header wie X-Powered-By, die exakte Versionen verkünden.
So behebst du es. Generische Fehlerseiten in der Produktion, die Details nur in deinen Logs. Entferne X-Powered-By (in Next.js poweredByHeader: false).
10. Domain und E-Mail bereit für echte Nutzer
Warum es wichtig ist. Wenn du E-Mails versendest (Bestätigungen, Passwort-Resets), landen sie ohne SPF, DKIM und DMARC im Spam oder, schlimmer, jeder kann Mails im Namen deiner Domain verschicken. Und ein ablaufendes Zertifikat oder eine ablaufende Domain legt die ganze Website lahm.
So prüfst und behebst du es. Veröffentliche SPF- und DMARC-Einträge im DNS, aktiviere DKIM bei deinem Versandanbieter und schalte die automatische Verlängerung für Domain und Zertifikat ein. Eine halbe Stunde Arbeit, die den schlimmstmöglichen Tag verhindert.
In welcher Reihenfolge du vorgehst, wenn du eine Stunde hast
- Zuerst Secrets im Frontend und Datenbankregeln: die zwei Lücken, die jedem echte Daten ausliefern.
- Dann exponierte Dateien und CORS: billig zu beheben und von automatischen Scannern stark abgeklopft.
- Danach Header, Cookies und Fehlerseiten: Sie härten, was schon funktioniert.
- Zuletzt Abhängigkeiten, Rate Limits und E-Mail: am Launch-Tag weniger dringend, in der Woche danach unverzichtbar.
Deine 2-Minuten-Checkliste vor dem Launch
- Kein
sk_live_,service_roleoder privater Key in deinem JavaScript; öffentliche Variablen geprüft. - HTTPS erzwungen, mit HSTS, X-Frame-Options, X-Content-Type-Options und einer CSP mindestens im Report-Modus.
- Row-Level Security (oder Firebase-Regeln) auf jeder Tabelle; der Inkognito-Test liefert leer.
.env,.git, Backups und Source Maps nicht erreichbar.- CORS auf deine eigenen Herkünfte beschränkt, nie die Herkunft mit Credentials gespiegelt.
- Cookies mit Secure, HttpOnly und SameSite.
npm auditohne kritische und hohe Funde.- Versuchslimits auf Login, Registrierung und KI-Endpoints; Ausgabenobergrenzen bei den Anbietern.
- Fehlerseiten ohne Traces; kein
X-Powered-By. - SPF, DKIM und DMARC veröffentlicht; automatische Verlängerung für Domain und Zertifikat.
Bring es einfach hinter dich
Statt all das von Hand zu prüfen, lass Scanaris laufen: Es prüft diese Punkte und rund 40 weitere auf deiner Live-Website in 30 Sekunden, sortiert die Funde nach Auswirkung und gibt dir für jeden einen fertigen Prompt, um ihn mit deiner KI zu beheben, bevor ihn jemand anderes findet. Schalte das Monitoring ein und es sagt dir, wenn nach dem Launch wieder etwas von dieser Liste kaputtgeht.
Häufig gestellte Fragen
Ersetzt das ein professionelles Sicherheitsaudit?
Nein. Diese Liste deckt ab, was sich von außen prüfen lässt und was in fast jeder KI-gebauten App schiefgeht. Ein Audit prüft zusätzlich deine Geschäftslogik, die Berechtigungen zwischen Nutzern und den Code selbst. Aber ohne diese Liste würde das Audit mit denselben Punkten anfangen.
Wie lange dauert das alles?
Prüfen: zehn Minuten mit einem Scanner oder eine halbe Stunde von Hand. Beheben: zwischen einem Nachmittag und einem Tag, je nachdem, wie viele Punkte durchfallen; Secrets und RLS dauern am längsten, weil sie dich zwingen, Code auf den Server zu verlagern.
Und nach dem Launch?
Geh die Liste jedes Mal durch, wenn die KI ein neues Feature generiert, das Daten oder Keys berührt, und richte einen wöchentlichen automatischen Re-Scan ein: Apps gehen durch Änderungen kaputt, nicht durch Zeit.