ai newsMo., 2. Nov.
EilmeldungClaude Batch API: Chạy tác vụ bất đồng bộ với chi phí chỉ bằng một nửa

API-Schlüssel im Browser offengelegt? Prüfen Sie Ihren OpenAI-, Claude- oder Gemini-Schlüssel in 2 Minuten

API-Schlüssel im Browser offengelegt? Prüfen Sie Ihren OpenAI-, Claude- oder Gemini-Schlüssel in 2 Minuten Wenn Ihre Web-App OpenAI, Claude oder Gemini direkt aus dem Browser aufruft, ist Ihr API-Schlüssel im Browser offengelegt, und jeder, der die DevTools öffnet, kann ihn kopieren. Sie können das

dev.toMontag 07:21 · 02.11.7 Min. Lesezeit
Bild: dev.to

Posted on Nov 2 • Originally published at apidog.com

Wenn Ihre Web-App OpenAI, Claude oder Gemini direkt aus dem Browser aufruft, ist Ihr API-Schlüssel im Browser offengelegt, und jeder, der die DevTools öffnet, kann ihn kopieren. Sie können das in 2 Minuten bestätigen: Öffnen Sie den Network-Tab, senden Sie eine KI-Anfrage und suchen Sie nach einem Authorization -, x-api-key - oder x-goog-api-key -Header, der an den Anbieter geht. Wenn Sie Ihren Schlüssel dort sehen, rotieren Sie ihn noch heute und verlagern Sie den Aufruf hinter eine Server-Route.

Unten: die Prüfung, die Reihenfolge der Behebung und wie Ihr Coding-Agent die korrigierte Route testen kann.

Ein im Browser offengelegter API-Schlüssel ist ein Geheimnis, das im Frontend-Code oder im Netzwerkverkehr mitgeliefert wird, wo jeder Besucher es lesen kann. Wenn der Browser den Schlüssel sendet, kann der Nutzer ihn kopieren und den Anbieter auf Ihre Rechnung aufrufen.

Googles Gemini API key guide sagt: „Do not hardcode API keys directly in web or mobile apps", weil „Keys compiled in client-side code can be extracted by users", und es wird empfohlen, „run a backend proxy server to make the actual API calls." OpenAIs API key safety guide gibt dieselbe Regel: Leiten Sie Anfragen über Ihr eigenes Backend, anstatt den Schlüssel an den Client auszuliefern.

Die openai-node README sagt, dass Browser-Unterstützung standardmäßig deaktiviert ist, „to avoid exposing your secret API credentials", und Sie müssen dangerouslyAllowBrowser: true setzen, um sie einzuschalten. Das TypeScript SDK von Anthropic verwendet denselben Optionsnamen, und seine API akzeptiert Browser-Aufrufe (CORS) nur, wenn die Anfrage den Header anthropic-dangerous-direct-browser-access: true trägt, wie Simon Willison dokumentierte, als es veröffentlicht wurde.

Das Muster ist häufig in Apps, die schnell mit KI-App-Buildern und Coding-Agents erstellt wurden: Der kürzeste funktionierende Weg ist ein Fetch aus einer React-Komponente mit dem Schlüssel in einer VITE_ - oder NEXT_PUBLIC_ -Variable. Gestohlene Schlüssel werden dann für Masseninferenz weiterverkauft, wie in unserem Beitrag über gestohlene KI-API-Schlüssel und LLMjacking behandelt, und Ihre Rechnung ist der Ort, an dem Sie es bemerken.

Führen Sie diese Prüfungen gegen die Produktion durch, nicht gegen localhost.

Network-Tab beobachten (45 Sekunden). Öffnen Sie Ihre Website, drücken Sie F12 (Cmd+Option+I auf einem Mac), wählen Sie den Network-Tab und lösen Sie eine KI-Funktion aus, z. B. das Senden einer Chat-Nachricht. Filtern Sie nach openai, anthropic oder googleapis. Wenn eine Anfrage direkt an api.openai.com, api.anthropic.com oder generativelanguage.googleapis.com geht, klicken Sie darauf und öffnen Sie Headers. Ein Schlüssel in [REDACTED CREDENTIAL], x-api-key, x-goog-api-key oder einem?key=`-Query-Parameter bedeutet, dass er offengelegt ist.

Das Bundle durchsuchen (45 Sekunden). Drücken Sie in den DevTools Cmd+Option+F (Ctrl+Shift+F unter Windows), um alle geladenen Skripte zu durchsuchen. Suchen Sie nach sk-, sk-ant-, AIza und dangerouslyAllowBrowser. Jeder Treffer in einer.js -Datei, die an den Browser ausgeliefert wird, ist ein Leck, selbst wenn noch keine Anfrage ausgelöst wurde.

Ihre Umgebungsvariablen-Präfixe prüfen (30 Sekunden). Öffnen Sie Ihre.env -Datei und Ihr Hosting-Dashboard. Build-Tools kopieren einige Variablen standardmäßig in das Client-Bundle: VITE_* in Vite (siehe Vite-Umgebungsvariablen-Dokumentation ), NEXT_PUBLIC_* in Next.js, REACT_APP_* in Create React App und EXPO_PUBLIC_* in Expo. Ein Anbieter-Schlüssel hinter einem dieser Präfixe ist öffentlich, egal wie er benannt ist.

Für einen Terminal-Scan Ihrer Build-Ausgabe:

grep -rnoE "sk-(proj-|ant-)?[A-Za-z0-9_-]{20,}|AIza[0-9A-Za-z_-]{35}" dist/ build/.next/static/ 2>/dev/null grep -rn "dangerouslyAllowBrowser" dist/ build/.next/static/ 2>/dev/null `

Leere Ausgabe ist bestanden. Google sagt, dass neue AI Studio-Schlüssel, die seit dem 28. Mai 2026 erstellt wurden, „auth keys" sind, deren Format von AIza abweichen kann. Suchen Sie daher auch im Bundle nach generativelanguage.googleapis.com. Sie bestehen nur, wenn der Browser mit Ihrer eigenen Domain spricht (zum Beispiel /api/chat ) und nirgendwo ein Anbieter-Hostname oder Schlüssel auftaucht.

Zuerst zu rotieren schließt das heutige Loch; die Architekturänderung schließt es dauerhaft.

Stellen Sie den neuen Schlüssel serverseitig bereit, bevor Sie den alten widerrufen, sonst fällt Ihre KI-Funktion aus. Unser Leitfaden zu Best Practices für die API-Schlüsselrotation behandelt Rotation ohne Ausfallzeit. Bei Schritt 4 empfiehlt OpenAIs Schlüsselsicherheitsleitfaden Ausgabenlimits mit harter Durchsetzung, da Warnungen allein den Datenverkehr nicht stoppen; ein Google Cloud-Abrechnungsbudget warnt Sie, stoppt aber die Nutzung nicht von selbst.

Eine Backend-Proxy-Route ist ein kleiner Server-Endpunkt, der die Eingabeaufforderung des Nutzers empfängt, den API-Schlüssel auf dem Server hinzufügt, den Anbieter aufruft und nur die Antwort zurückgibt. Der Browser sieht den Schlüssel nie. Hier ist eine minimale Next.js-Route für OpenAI; Claude und Gemini folgen demselben Muster:

`ts // app/api/chat/route.ts (runs on the server only) import OpenAI from "openai"; import { getSession } from "@/lib/auth"; // your auth helper import { checkRateLimit } from "@/lib/limits"; // your per-user limiter

const client = new OpenAI({ [REDACTED CREDENTIAL] }); // no NEXT_PUBLIC_ prefix

export async function POST(req: Request) { const session = await getSession(req); if (!session) return new Response("Unauthorized", { status: 401 });

if (!(await checkRateLimit(session.userId, 20))) { // 20 requests per minute return new Response("Too many requests", { status: 429 }); }

const { message } = await req.json(); if (typeof message!== "string" || message.length > 4000) { return new Response("Bad request", { status: 400 }); }

const response = await client.responses.create({ model: process.env.OPENAI_MODEL!, // pin the model server-side input: message, });

return Response.json({ reply: response.output_text }); // return the answer, nothing else } `

Was es sicher macht, nicht nur versteckt:

Verwenden Sie für Claude und Gemini deren SDKs mit ANTHROPIC_API_KEY oder GEMINI_API_KEY. Googles Website- und IP-Beschränkungen helfen, aber jeder mit curl kann jeden Referer -Header senden, also behandeln Sie sie als zweite Schicht. Der einzige faire Fall für Browser-Aufrufe ist ein Bring-Your-Own-Key-Tool, bei dem jeder Nutzer seinen eigenen Schlüssel einfügt.

Den Schlüssel zu verschieben ist die eine Hälfte; die andere Hälfte ist zu beweisen, dass er verschoben bleibt, nachdem Ihr Agent das nächste Feature geschrieben hat. Lassen Sie den Agenten, der die Route erstellt hat, sie mit Apidog CLI testen. Richten Sie es einmal ein:

bash npm install -g apidog-cli@latest apidog login --with-token <YOUR_TOKEN> npx -y skills add https://apidog.com # pick your agent when prompted

Geben Sie dann Claude Code, Codex, Cursor oder welchem Agenten Sie auch verwenden, einen [REDACTED PROMPT] Create Apidog test cases in project for POST /api/chat on our staging environment that assert:

Der Agent liest das Schema, validiert seine Payload, schreibt die Testfälle und führt sie aus:

`bash apidog test-case category --project <id> apidog cli-schema get test-case-create apidog cli-schema validate test-case-create --file case.json apidog test-case create --project <id> --file case.json apidog run --test-case <caseId> --project <id> -e <envId> -r cli,json `

Die zweite Zusicherung ist die wichtigste: Sie schlägt in dem Moment fehl, in dem ein Anbieter-Fehlerobjekt oder Debug-Feld beginnt, Ihren Schlüssel an den Client zurückzuspiegeln. Fügen Sie denselben apidog run... -r junit -Schritt in Ihre Pipeline ein, damit jede Bereitstellung es erneut prüft; unser Apidog CLI CI/CD-Leitfaden zeigt das Setup, und Apidog CLI in Claude Code behandelt die Agent-Seite. Der kostenlose Plan von Apidog deckt bis zu 4 Benutzer ab, sodass ein kleines Team dies ohne kostenpflichtigen Platz ausführen kann.

Für die Repo-Seite desselben Problems, Schlüssel, die in Git committet statt an den Browser ausgeliefert werden, siehe unseren API-Schlüssel-Leck-Check mit einem Secret-Scanner. Wenn Ihre Agenten Tools aufrufen, die Kundendaten verarbeiten, behandelt Testen von KI-Agenten auf Datenlecks die nächste Ebene.

Wie erkenne ich, ob mein OpenAI API-Schlüssel im Browser offengelegt ist? Lösen Sie eine KI-Funktion mit geöffnetem DevTools Network-Tab aus. Eine Anfrage an api.openai.com mit einem Authorization: Bearer [REDACTED]-... -Header bedeutet, dass er offengelegt ist. Durchsuchen Sie außerdem geladene Skripte nach sk- und dangerouslyAllowBrowser.

Ist es sicher, einen API-Schlüssel in einer NEXT_PUBLIC_ oder VITE_-Umgebungsvariable zu speichern? Nein. Diese Präfixe existieren, um Werte in das Client-Bundle zu kopieren. Jeder Anbieter-Schlüssel, der darunter gespeichert ist, wird an jeden Besucher ausgeliefert. Verwenden Sie eine präfixlose, nur serverseitige Variable und lesen Sie sie innerhalb einer Server-Route.

Macht es einen Gemini-API-Schlüssel sicher im Browser, wenn ich ihn auf meine Website beschränke? Es hilft, aber ein Skript außerhalb des Browsers kann jeden Referer -Header senden. Googles eigener Leitfaden empfiehlt einen Backend-Proxy für Client-Apps.

Ich habe festgestellt, dass mein Schlüssel offengelegt ist. Was sollte ich zuerst tun? Erstellen Sie einen neuen Schlüssel, stellen Sie ihn serverseitig bereit und widerrufen Sie dann den alten. Als Nächstes verlagern Sie den Aufruf hinter eine authentifizierte Route mit Rate-Limits pro Nutzer und legen Sie Ausgabenlimits beim Anbieter fest.

Kann mein Coding-Agent das für mich beheben und testen? Ja. Bitten Sie ihn, den Anbieteraufruf in eine Server-Route zu verlagern, und verwenden Sie dann Apidog CLI, um Tests zu erstellen und auszuführen, die eine 401 ohne Sitzung, keine Schlüsselmuster in Antworten und eine 429 nach Überschreiten Ihres Rate-Limits zusichern.

Quelle: dev.to (dev.to). Original öffnen