跳到正文
DEV Community· TANK JAY·· 2 小時前AI 評分53

OpenAI API key 如何透過 NEXT_PUBLIC_、VITE_ 和 dangerouslyAllowBrowser 暴露於瀏覽器

OpenAI API key exposed in the browser: NEXT_PUBLIC_, VITE_ and dangerouslyAllowBrowser

AI 導讀

文章指出,將 OpenAI API key 放入 NEXT_PUBLIC_、VITE_* 等前端變數,或啟用 dangerouslyAllowBrowser,會令 key 出現在訪客下載的 JavaScript 中。

正文

The client said undefined, so the key got a prefix. Then the SDK refused to run in the browser, so it got a flag:

"use client";
const openai = new OpenAI({
  apiKey: process.env.NEXT_PUBLIC_OPENAI_API_KEY,
  dangerouslyAllowBrowser: true,
});

It works. And the OpenAI API key is now in plain text in a JavaScript file every visitor downloads. (A made-up example, but a very common one.)

Prefixes publish values

  • Next.js inlines NEXT_PUBLIC_ values "into any JavaScript sent to the browser".
  • Vite: "VITE_* variables should not contain sensitive information such as API keys."
  • Create React App: "Do not store any secrets (such as private API keys) in your React app!"

The OpenAI and Anthropic JS SDKs block browsers by default "to avoid exposing your secret API credentials". dangerouslyAllowBrowser: true switches that guard off.

Five ways AI keys reach the bundle

  1. A public prefix on the key (.env, CI, Dockerfile)
  2. Reading that variable in client code
  3. dangerouslyAllowBrowser: true
  4. A server-only key in a "use client" file (and the "fix" of adding a prefix)
  5. Vite define, webpack DefinePlugin, next.config env

Plus a key pasted into a component "just to test".

Fix: call the provider from a server route with a server-only variable, have the page call that route, and rotate any key that was ever deployed. Deleting it from the code is not enough: old builds and caches still have it. In a Vite app with no server, a small serverless or edge function does the same job.

Checked in VS Code

I built BrowserKey, a free VS Code extension that catches all of these for Next.js, Vite, CRA, Expo, Nuxt, Gatsby, SvelteKit and Astro, and for OpenAI, Anthropic, Gemini, Groq, xAI, OpenRouter and more. Six rules, a Quick Fix to rename to a server-only variable, and an activity bar panel:

NEXT_PUBLIC_OPENAI_API_KEY in .env.local is bundled into the browser
new OpenAI({ dangerouslyAllowBrowser: true }) exposes the API key
hardcoded OpenAI key sk-proj-**** in browser code

Keys are always masked. No network, no telemetry, no child processes.

code --install-extension jaytankdev.browserkey

Source (MIT): github.com/jay-tank/browserkey

Full write-up (framework docs, the server route fix, all six rules, FAQ): OpenAI API key exposed in the browser

來源:DEV Community · dev.to