Befund erklärt
API-Schlüssel im Frontend: Was der Befund bedeutet
Wenn ein API-Schlüssel im ausgelieferten JavaScript steht, kann ihn jeder Besucher deiner Seite lesen — dafür genügen die Entwicklertools des Browsers. Automatisierte Bots durchsuchen öffentlich erreichbare Bundles gezielt nach solchen Schlüsseln und benutzen sie innerhalb von Minuten. Der wichtigste Schritt ist deshalb nicht, den Schlüssel aus dem Code zu entfernen, sondern ihn beim Anbieter zu widerrufen: Er gilt als kompromittiert, sobald er einmal ausgeliefert wurde, und ein neues Bundle macht das alte nicht ungeschehen.
Der Scan ist kostenlos und dauert etwa zwanzig Sekunden. Du siehst sofort, wie viele Befunde es gibt und wie schwer sie wiegen.
Eigene App kostenlos scannenIn dieser Reihenfolge vorgehen
Erstens: Schlüssel beim Anbieter widerrufen. Sofort, nicht nach dem Umbau. Solange er gültig ist, kann er benutzt werden — und die Rechnung geht an dich.
Zweitens: Neuen Schlüssel erzeugen und ihn dort ablegen, wo er nicht ausgeliefert wird — in den Umgebungsvariablen deines Servers oder deiner Funktion, nicht in einer Datei mit `VITE_`-Präfix.
Drittens: Den Aufruf verlagern. Das Frontend ruft künftig deine eigene Route auf, und die spricht mit dem Anbieter. Damit sieht der Browser den Schlüssel nie.
Viertens: Abrechnung prüfen. Wenn der Schlüssel länger öffentlich war, sieh in der Nutzungsübersicht des Anbieters nach, ob dort etwas steht, das nicht von dir stammt.
Warum der Schlüssel überhaupt dort gelandet ist
Fast immer über das `VITE_`-Präfix. Vite setzt jede Variable mit diesem Präfix beim Bauen fest in das Bundle ein — das ist der Zweck des Präfixes. Der Name sagt nichts darüber, ob der Wert geheim sein soll.
Bei Next.js gilt dasselbe für `NEXT_PUBLIC_`. Beide Präfixe bedeuten wörtlich „das darf öffentlich sein“, und beide werden regelmäßig für Werte benutzt, die es nicht dürfen.
Der zweite Weg ist das SDK selbst. `new OpenAI({ apiKey, dangerouslyAllowBrowser: true })` funktioniert — die Bibliothek warnt im Namen der Einstellung, dass das nicht vorgesehen ist.
Welche Schlüssel dürfen ins Frontend?
Öffentlich und unbedenklich: Supabase `anon`, Firebase-Konfiguration, Stripe `pk_`-Schlüssel, Google-Maps-Schlüssel mit gesetzter Verweiser-Einschränkung. Diese Werte identifizieren dein Projekt, nicht eine Berechtigung.
Niemals ins Frontend: OpenAI und Anthropic, Stripe `sk_`, Supabase `service_role`, AWS-Zugangsdaten, SMTP-Passwörter, alles was „secret“ oder „service“ heißt.
Bei Google-Schlüsseln gibt es einen Zwischenfall-Klassiker: Der Schlüssel ist zwar für das Frontend gedacht, aber ohne Einschränkung auf deine Domain. Dann kann ihn jeder auf seiner eigenen Seite einsetzen, und die kostenpflichtigen Aufrufe laufen über dein Konto.
Der Aufruf gehört auf den Server
Das Muster ist bei allen Anbietern gleich: eine kleine eigene Route, die den Schlüssel hält und die Anfrage weiterreicht. Bei Supabase eine Edge Function, bei Vercel eine Route unter `api/`, bei Netlify eine Function.
Vergiss dabei nicht, die eigene Route abzusichern. Sonst hast du den Schlüssel versteckt, aber jeder kann ihn weiterhin auf deine Kosten benutzen — nur eben über deinen Umweg.
// api/chat.ts — der Schlüssel bleibt auf dem Server
export default async function handler(req, res) {
// Erst prüfen, WER fragt. Ohne das ist die Route
// ein öffentlicher Zugang zu deinem Kontingent.
const nutzer = await pruefeAnmeldung(req);
if (!nutzer) return res.status(401).json({ error: 'Nicht angemeldet.' });
const antwort = await fetch('https://api.openai.com/v1/chat/completions', {
method: 'POST',
headers: {
authorization: `Bearer ${process.env.OPENAI_API_KEY}`,
'content-type': 'application/json',
},
body: JSON.stringify(req.body),
});
res.status(antwort.status).json(await antwort.json());
}Reicht es, das Bundle neu zu bauen?
Nein. Ein neues Bundle entfernt den Schlüssel aus der aktuellen Datei — aber die alte war öffentlich erreichbar, oft über Wochen. Sie kann in Archivdiensten liegen, in Browser-Caches, in den Datenbanken der Bots, die sie eingesammelt haben.
Deshalb ist der Widerruf der eigentliche Schritt. Alles andere verhindert nur die Wiederholung.
Das prüfen wir automatisch
- Schlüsselmuster im ausgelieferten JavaScript
- Google-Schlüssel ohne Einschränkung (Deep-Scan)
- Erreichbare .env- und .git-Dateien
Häufige Fragen
- Wie schnell wird ein öffentlicher Schlüssel missbraucht?
- Schneller, als man annimmt. Es gibt automatisierte Sammler, die öffentliche JavaScript-Bundles und Code-Repositorien gezielt nach Schlüsselmustern durchsuchen. Bei bekannten Formaten — etwa dem `sk-`-Präfix von OpenAI — vergehen zwischen Veröffentlichung und erstem fremden Aufruf regelmäßig nur Minuten.
- Ich habe den Schlüssel entfernt. Muss ich ihn trotzdem widerrufen?
- Ja. Ein Schlüssel, der einmal ausgeliefert wurde, gilt als kompromittiert. Ihn nur zu entfernen verhindert die nächste Auslieferung, nicht die Nutzung durch jemanden, der ihn bereits hat.
- Der Schlüssel steht in meiner .env — ist das nicht sicher?
- Das kommt auf das Präfix an. Eine `.env` wird beim Bauen ausgewertet, und alles mit `VITE_` oder `NEXT_PUBLIC_` landet fest im Bundle. Die Datei selbst wird nicht ausgeliefert, ihr Inhalt aber sehr wohl. Prüfe zusätzlich, ob die `.env` versehentlich im öffentlichen Verzeichnis liegt — das ist ein eigener Befund.
- Wie finde ich alle Schlüssel in meiner App?
- Von Hand: In den Entwicklertools das größte Bundle öffnen und nach `sk-`, `sk_live`, `service_role` und `AKIA` suchen. Automatisch: Unser Scan prüft das ausgelieferte JavaScript gegen rund sechzig Schlüsselmuster verschiedener Anbieter.