akanjilal.dev
Live demo

Prompt injection, demonstrated against a live model

This is the real code from the llm-security-lab repository, running in your browser through Pyodide, which is Python compiled to WebAssembly. There is no server and no API key. A deterministic mock model stands in for a real one and fails in the way real models do, by giving too much weight to the most forceful instruction it sees. Type an attack below and watch the same request go through a vulnerable path and a hardened path side by side.

Booting the Python runtime in your browser, this takes a few seconds the first time…

Scenario A. Direct injection

The attacker talks to the assistant directly and tries to make it reveal the confidential operator key it was told to protect.

Vulnerable

Hardened

Scenario B. Indirect injection, through a poisoned document

The attacker never talks to the assistant. They hide an instruction inside a document the assistant is later asked to summarize. This is the vector that grows as agents read web pages, emails, and tool output.

Vulnerable

Hardened

The hardened paths succeed through engineering controls rather than a stricter prompt. Layer one is an input guard that catches obvious override language. Layer two wraps untrusted content in an explicit data boundary so the model is told to treat it as data, not instructions. Layer three scans the output and redacts known secrets as a last resort. Each scenario maps to the OWASP Top 10 for language model applications (LLM01 prompt injection, LLM02 sensitive information disclosure), to MITRE ATLAS, and to the NIST framework. If you remove any one of these layers in the repository, a corresponding test fails.