Lessons · LLM08: Hidden Context Exposure · error

Your system prompt ships to the browser

A prompt in a client component is in the JavaScript every visitor downloads.

Caught by system-prompt-leakage-in-client-bundle · CWE-200, CWE-540

What is wrong

The system prompt (or a guardrail, persona, or instruction constant) is declared in a file marked 'use client'.

Everything in a client module is bundled into the JavaScript sent to the browser. Anyone can open DevTools, search the bundle, and read it.

Worse, if the client sends the prompt to your API, an attacker can send their own prompt instead. Your server would use it.

How it is used against you

Your chat component keeps SYSTEM_PROMPT next to the input box and sends it with each message.

"use client";
const SYSTEM_PROMPT = "You are Acme's assistant. Never discuss pricing.";
  1. A competitor opens your site, opens DevTools, and searches the JavaScript for 'You are'.
  2. They copy your full prompt, which is the product you spent weeks tuning.
  3. Then they replay your API request with their own system prompt in its place. Your server forwards it to the model on your bill.

The cost: Your prompt is public, any rule in it can be read and worked around, and your endpoint may become a free proxy to the model.

How to spot it

  • SYSTEM_PROMPT, instructions, persona, or guardrail constants in a file with 'use client' at the top.
  • A system field built in a React component.
  • A fetch to your chat API that sends the system prompt in the body.

The fix

Paste this into Claude Code, Cursor, or whatever wrote the code. When llm-audit finds the mistake in your project, npx llm-audit prompt gives you the same prompt with every file and line filled in.

Fix this in my project: a system prompt or instruction text is declared in a client-side module, so it ships to the browser.

Please:
1. Move the prompt to a route handler, a Server Action, or a module that starts with import "server-only".
2. Have the client send only the user's text.
3. On the server, ignore any system prompt the client sends.

Show me the diff and confirm the prompt text no longer appears in any client file.

Check the rest

A prompt that looks for the same mistake everywhere else, without changing anything yet.

Check this project for AI prompts that end up in the browser bundle, before I ship it.

Look for:
- System prompts, instructions, personas, or guardrail text in files marked 'use client' or imported by them.
- Client code that sends a system prompt to the API.
- Server routes that accept a system prompt from the request.

For each one, give me the file and line and say what a visitor could read or change. Do not change any code yet.

Find it in your code

npx llm-audit scan

Runs on your machine with Semgrep. Nothing is uploaded.