1. API-Keys, die in dein Frontend-JavaScript eingebacken sind
Das ist der schädlichste Fehler und der am leichtesten zu machende. Du bittest dein KI-Tool, „Stripe-Zahlungen hinzuzufügen“ oder „mit OpenAI zu verbinden“, und es verdrahtet den Secret Key direkt in eine Client-Komponente. Die App funktioniert — und dein Secret Key wird nun an den Browser jedes Besuchers ausgeliefert, lesbar für jeden, der die DevTools öffnet oder dein JS-Bundle durchsucht.
Alles mit dem Präfix NEXT_PUBLIC_ (oder VITE_ oder REACT_APP_) wird zur Build-Zeit in das Client-Bundle eingebettet. Secret Keys — Stripe sk_live_, OpenAI sk-, Datenbank-URLs, Service-Role-Keys — dürfen nur in serverseitigem Code gelesen werden: API-Routes, Server-Komponenten oder Edge-Funktionen.
Die schnelle Prüfung: Öffne deine deployte Website, sieh dir den Seitenquelltext und das gebündelte JS an und suche nach sk_live, sk- und den ersten Zeichen der Keys in deiner .env. Taucht einer davon auf, rotiere zuerst den Key und verlagere dann den Aufruf auf den Server.
2. .env oder .git direkt aus deinem Web-Root ausgeliefert
Eine überraschende Zahl deployter Apps gibt bereitwillig ihre .env-Datei — oder ihr gesamtes .git-Verzeichnis — zurück, wenn man einfach danach fragt. Ein fehlkonfigurierter Static-File-Server oder eine Framework-Vorlage, die alles in den public-Ordner kopiert, genügt schon.
Die Auswirkung ist total: Datenbank-Zugangsdaten, Auth-Secrets, API-Keys, alles in einer Datei. Ein offengelegtes .git-Verzeichnis ist fast genauso schlimm, weil ein Angreifer deinen kompletten Quellcode-Verlauf rekonstruieren kann, einschließlich Secrets, die committet und später „entfernt“ wurden.
Die schnelle Prüfung dauert zehn Sekunden:
curl -i https://yourapp.com/.env
curl -i https://yourapp.com/.git/config
# Both should return 404 (or 403) — never 200.Offengelegte .env-Dateien: der vollständige Guide3. Keine Content-Security-Policy
KI-Tools fügen fast nie Security-Header hinzu, und die CSP ist der wichtigste. Ohne sie erlaubt ein einziger HTML-Injection- oder XSS-Bug irgendwo in deiner App einem Angreifer, beliebiges JavaScript in den Browsern deiner Nutzer auszuführen — Sitzungen stehlen und Daten exfiltrieren.
Eine gute Ausgangs-Policy für die meisten Apps: default-src 'self', Objekte und Framing blockieren und nur die Drittanbieter-Script-Origins erlauben, die du wirklich nutzt. Beginne strikt, lockere bewusst — niemals umgekehrt.
// next.config.js
const csp = [
"default-src 'self'",
"script-src 'self'",
"style-src 'self' 'unsafe-inline'",
"img-src 'self' data:",
"base-uri 'none'",
"frame-ancestors 'none'",
"object-src 'none'",
].join("; ");
module.exports = {
async headers() {
return [{ source: "/:path*", headers: [{ key: "Content-Security-Policy", value: csp }] }];
},
};CSP erklärt: Direktiven, Nonces und häufige Fehler4. Session-Cookies ohne Secure, HttpOnly und SameSite
Wenn deine Auth-Bibliothek von einem KI-Tool mit Standardoptionen verdrahtet wurde, lohnt es sich, die Flags des Session-Cookies zu überprüfen. Ein Cookie ohne HttpOnly kann von jedem eingeschleusten Skript gelesen werden (was aus einem kleinen XSS eine vollständige Account-Übernahme macht), eines ohne Secure kann über einfaches HTTP lecken, und eines ohne SameSite macht Cross-Site Request Forgery deutlich einfacher.
Öffne DevTools → Application → Cookies auf deiner deployten App. Jedes Session- oder Auth-Cookie sollte alle drei zeigen: Secure, HttpOnly und SameSite=Lax (oder Strict).
5. HTTP, das nie zu HTTPS wird (und kein HSTS)
Die meisten Hosting-Plattformen geben dir HTTPS automatisch — aber viele Apps antworten trotzdem bereitwillig über einfaches HTTP, ohne weiterzuleiten, oder leiten weiter, senden aber nie einen Strict-Transport-Security-Header. In beiden Fällen macht ein Nutzer, der deine Domain in die Adressleiste eintippt, seine erste Anfrage unverschlüsselt, und diese Anfrage kann abgefangen oder herabgestuft werden, bevor deine Weiterleitung stattfindet.
Die Lösung sind zwei Zeilen Konfiguration: eine permanente 301-Weiterleitung von HTTP zu HTTPS plus ein HSTS-Header (max-age=31536000; includeSubDomains), damit Browser sich weigern, jemals wieder herabzustufen.
6. CORS so gesetzt, dass alles erlaubt ist
Wenn ein KI-generiertes Frontend während der Entwicklung seine eigene API nicht erreichen kann, ist die generierte „Lösung“ fast immer Access-Control-Allow-Origin: * — manchmal sogar mit erlaubten Credentials. Das sagt jeder Website im Internet, dass sie deine API aus den Browsern ihrer Besucher aufrufen darf.
Für eine API, die dein eigenes Frontend bedient, sollte der erlaubte Origin genau deine eigene Domain sein und sonst nichts. Wildcard-CORS ist nur für wirklich öffentliche, nicht authentifizierte, schreibgeschützte APIs akzeptabel.
7. Kein SPF oder DMARC auf deiner Domain
Dieser Punkt betrifft gar nicht den Code deiner App — sondern deine Domain. Ohne die DNS-Records SPF und DMARC kann jeder E-Mails senden, die vorgeben, von [email protected] zu stammen, und empfangende Mailserver haben keine Möglichkeit, zu erkennen, dass sie gefälscht sind. Das ist Phishing gegen deine eigenen Nutzer, im Gewand deiner Marke.
Zwei DNS-TXT-Records beheben das. Wenn du E-Mails über einen Anbieter wie Resend, Postmark oder SES sendest, gibt dir deren Dokumentation den exakten SPF-Wert; füge daneben eine DMARC-Policy hinzu und ziehe sie von p=none auf p=quarantine an, sobald du bestätigt hast, dass legitime Mail besteht.
Prüfe alle sieben in einem Durchgang
Jeder Punkt auf dieser Liste ist von außen erkennbar, was bedeutet, dass du ihn nicht von Hand durchgehen musst. AppSafe führt all diese Prüfungen — plus SSL/TLS, Subdomain-Takeover, Source Maps und mehr — in einem einzigen Scan aus, benotet das Ergebnis von A bis F und gibt dir für jeden Befund einen KI-Fix-Prompt, den du direkt zurück in Cursor oder Claude Code einfügen kannst.
Der Schnell-Scan auf der Startseite braucht keine Anmeldung. Der vollständige Scan (einschließlich der Prüfungen auf offengelegte Secrets) läuft nur auf Domains, deren Inhaberschaft du verifiziert hast — bewusst so, denn wir durchsuchen nicht die JS-Bundles einer anderen Person nach Keys.