AI API key is not accessible client-side
Why it matters
An AI API key accessible from client-side code is not a secret—it is a public credential embedded in a bundle downloaded by every browser that visits your site. CWE-312 (cleartext credential storage) and CWE-798 (hardcoded credential) both apply. OWASP A02:2021 (Cryptographic Failures) covers this class of exposure. Any attacker can extract the key from browser DevTools in under 30 seconds and use it to: exhaust your API quota (generating costs you bear), extract your system prompt by calling the provider directly, or abuse the provider's API for their own applications at your expense. In Next.js, prefixing any environment variable with NEXT_PUBLIC_ embeds its value in the client bundle at build time—this is the most common accidental exposure vector in production deployments.
Severity rationale
High because client-side key exposure requires no attack sophistication—the credential is readable in plain text from browser DevTools, making exploitation trivial and immediate once discovered.
Remediation
All AI API calls must be proxied through server-side routes. The AI SDK is never imported in client components, and the API key environment variable never carries a NEXT_PUBLIC_ prefix.
// Correct: server-side only (src/app/api/chat/route.ts)
import OpenAI from 'openai'
// Note: no NEXT_PUBLIC_ prefix — this variable is never in the client bundle
const openai = new OpenAI({ apiKey: process.env.OPENAI_API_KEY })
export async function POST(req: Request) {
// All AI calls happen here, server-side
}
// Client component (src/components/ChatWidget.tsx)
// No OpenAI import — just a fetch to your own API route
async function sendMessage(message: string) {
return fetch('/api/chat', {
method: 'POST',
body: JSON.stringify({ message })
})
}
If you have an existing NEXT_PUBLIC_OPENAI_API_KEY in .env or .env.example, rotate the key immediately before removing the prefix—it should be treated as compromised.
DetectionPro
The detection method for this pattern is part of AuditBuffet Pro.
The full method (what to look for, pass and fail conditions, and how results get reported) ships inside the AI Prompt Injection Audit. The pattern definition, severity rationale, and remediation remain openly licensed under CC-BY-4.0.
External references
- cwe · CWE-312 — Cleartext Storage of Sensitive Information
- cwe · CWE-798 — Use of Hard-coded Credentials
- owasp:2021 · A02 — Cryptographic Failures
- nist-ai-rmf:1.0 · GOVERN 1.1 — Policies, processes, procedures, and practices across organization to manage AI risks
Taxons
History
- 2026-04-18·v1.0.0·Initial import from ai-prompt-injection·automated