McKinsey Lilli Compromise: When SQL Injection Reaches the AI Prompt Layer
This chain starts with an old-fashioned web bug. Lilli (McKinsey's internal AI platform) exposed 22 unauthenticated API endpoints, and one of them built SQL from attacker-controlled JSON keys. CodeWall used that path to read and write the database behind McKinsey's AI platform: 46.5M chat messages, 728K files, 3.68M RAG chunks, vector-store metadata, and the system prompts shaping 43,000+ users.
The important point is not just that SQL injection happened. It is that one web bug reached the prompt and retrieval tables, so the compromise landed directly in the AI layer.
Threat Analysis
- Step 1: start with the unauthenticated API surface. Lilli exposed 22 endpoints without authentication. That gave CodeWall's autonomous agent a wide place to probe without needing an account first.
- Step 2: use one endpoint that turns JSON keys into SQL. One API built SQL queries from attacker-controlled JSON keys. CodeWall reports database read/write access through SQL injection within about 2 hours. It separately chained SQL injection with insecure direct object references (IDOR) to read individual employees' search histories.
- Step 3: realize the database also holds the AI platform's crown jewels. The exposed tables were not just ordinary business records. They included 46.5M chat messages, 728K files, 3.68M RAG chunks with S3 paths, vector-store metadata, AI assistants, and 95 prompt/model configurations across 12 models.
- Step 4: move from reading the AI layer to rewriting it. The same SQLi allowed UPDATE. That meant an attacker could change a system prompt, poison retrieved content, remove model-level safety instructions, or insert exfiltration instructions with a simple HTTP request and without touching application code. These are potential effects of verified write access, not demonstrated prompt poisoning or a bypass of independently enforced backend authorization.
- Why this matters: Lilli ran this way for 2 years with 43K+ users and 500K+ monthly prompts. CodeWall reports that ZAP missed the injection and its agent found the path; this is not an independent comparison of all automated or manual testing. McKinsey closed the unauthenticated endpoints and patched the issue on 2026-03-02 after CodeWall's 2026-03-01 report.
Applicable AIDEFEND Defenses (5)
What Defenders Should Do Now
- Inventory the exact prompt, RAG, vector-metadata and agent-configuration population and verify signed versions before loading or retrieval.
- Use safe SQL construction for both values and identifiers, exact API schemas, and default-deny authentication and object authorization on every route.
- Monitor unexpected writes to AI control data through independently protected database and runtime collectors; investigate rather than infer automatic containment.
- Separate asset stores and least-privilege identities, then test cross-store access and all routes that could bypass lifecycle gates.
- Add authorized, bounded security regression and red-team testing. Record what each test covered; autonomous testing supplements other AppSec methods and cannot guarantee complete discovery.
2 additional considerations
Blast-radius isolation between AI asset classes
Security testing coverage
Conclusion
McKinsey Lilli is a clear example of how an old web bug becomes a very modern AI-platform failure. Once SQL injection reached the prompt and retrieval tables, the attacker was no longer just looking at a database; they were in a position to rewrite how the system answered. AIDEFEND 's prompt-integrity, chunk-signing, and staged-authorization techniques map directly to that problem. The operational lesson is to treat prompts, RAG chunks, and vector metadata as assets that need their own integrity controls, not as ordinary rows sitting safely inside a database.
Last updated: