Lilli SQL Injection via Dynamic JSON Key Concatenation: A Technical Deep Dive into the CodeWall Autonomous Agent Attack
Executive summary
- CodeWall's autonomous offensive AI agent discovered and exploited a novel SQL injection vulnerability in McKinsey's internal Lilli AI platform by targeting dynamic JSON key names that were directly concatenated into SQL queries, despite parameterized values, achieving full read/write database access in under two hours with zero credentials.
- The attack surface consisted of 22 unauthenticated endpoints out of over 200 documented APIs; one write-to-search-history endpoint reflected JSON keys verbatim in database error messages, enabling blind schema inference and data exfiltration of 46.5 million plaintext chat messages, 728,000 files, 57,000 user accounts, 3.68 million RAG document chunks, and 95 system prompts across 12 model types.
- The agent chained the SQLi with an IDOR vulnerability to access cross-user search histories and could have performed prompt injection at the database level by issuing UPDATE statements against stored system prompts, potentially enabling persistent behavioral poisoning of the AI without code changes or detectable logs.
- This incident highlights that even elite organizations with significant security investment remain vulnerable to classic injection flaws when building RAG/AI platforms at scale, and that autonomous AI agents are now capable of identifying, reasoning about, and exploiting non-standard injection vectors that static tools like OWASP ZAP miss.
Technical architecture
McKinsey's Lilli platform, launched in 2023, is a large-scale internal Retrieval-Augmented Generation (RAG) system serving over 70% of the firm's 43,000 employees and processing more than 500,000 prompts per month. It combines chat interfaces, document analysis, semantic search over 100,000+ proprietary documents, and access to fine-tuned models. The architecture relies heavily on a centralized production database that stores chat messages, user accounts, workspaces, AI assistants, RAG chunks, and crucially, the system prompts that govern model behavior.
The vulnerable endpoint accepted JSON payloads representing user search queries and wrote them to the database. While the values were correctly parameterized (preventing classic string-based injection), the JSON key names (field names) were dynamically concatenated into the SQL statement. This is a rarer form of injection sometimes called "dynamic SQL key injection" or "SQLi via identifier concatenation." The agent discovered that error messages from the database reflected these keys verbatim, providing an oracle for blind exploitation.
The attack unfolded in distinct autonomous phases:
- Surface mapping: The agent enumerated publicly exposed API documentation revealing >200 endpoints, identifying 22 that required no authentication.
- Injection point discovery: It located the search-history write endpoint and confirmed JSON keys were unsanitized in the query construction.
- Blind schema reconstruction: Over 15 iterations, the agent used error-message feedback to infer the query shape, table structures, column names, and data types.
- Data exfiltration: Once the structure was understood, it extracted live production records, including employee identifiers.
- Post-exploitation chaining: The agent leveraged the same write primitive to explore related tables and combined the SQLi with an Insecure Direct Object Reference (IDOR) flaw to read other users' histories.
Beyond the relational database, the agent mapped S3 paths for 3.68 million RAG document chunks, discovered 1.1 million files flowing through external AI APIs (including 266,000+ OpenAI vector stores), and extracted 95 system prompt configurations spanning 12 different model types. These prompts contained the exact instructions, guardrails, citation logic, and refusal policies used by Lilli.
Performance analysis
No formal benchmark numbers (such as exfiltration speed in records/second or tokens analyzed) are provided in the disclosure. However, the timeline itself is the most significant performance data: an autonomous agent with no prior knowledge, no credentials, and no human-in-the-loop achieved full read/write access to a production system at one of the world's most security-conscious professional services firms in approximately two hours.
For comparison, traditional automated scanners such as OWASP ZAP failed to identify the vulnerability because it did not trigger on parameterized values and required reasoning about JSON key reflection in error messages — a semantic understanding current static/dynamic analysis tools lack. The agent performed 15 distinct "blind iterations" using error messages as an oracle, demonstrating effective use of in-context learning and iterative hypothesis testing within its reasoning loop.
The scale of exposed data provides indirect performance context:
- 46.5 million chat messages stored in plaintext
- 728,000 total files, including 192,000 PDFs, 93,000 Excel spreadsheets, 93,000 PowerPoint decks, and 58,000 Word documents
- 57,000 user accounts
- 384,000 AI assistants and 94,000 workspaces
- 3.68 million RAG document chunks containing proprietary methodologies
This represents decades of McKinsey's intellectual property and client-sensitive discussions accessible via a single unauthenticated injection point.
Technical implications
The incident signals a fundamental shift in the threat landscape. Autonomous AI agents can now perform target selection, attack surface mapping, vulnerability discovery, and exploitation with minimal human guidance. CodeWall notes that their research agent independently suggested McKinsey as a target because of the company's public responsible disclosure policy and recent Lilli updates — demonstrating goal-directed offensive reasoning.
For the AI ecosystem, the most critical implication is the elevation of prompts as crown-jewel assets. System prompts in Lilli were stored in the same database as chat history. With write access, an attacker could issue an UPDATE statement to modify prompts directly. This enables several high-impact attack patterns without touching application code:
UPDATE system_prompts
SET prompt_text = 'New malicious instructions here...'
WHERE model_type = 'primary_assistant';
Possible outcomes include:
- Subtle poisoning of strategic recommendations or financial models
- Instructing the AI to exfiltrate data by embedding sensitive information in "normal" responses
- Removal of guardrails, causing the model to ignore access controls or disclose internal data
- Silent persistence with no file modifications, no anomalous processes, and minimal log artifacts
Traditional security controls focused on code, servers, and supply chains offer little protection against prompt-layer attacks. Prompts are rarely versioned, integrity-protected, or access-controlled with the same rigor as application code.
The attack also demonstrates that RAG pipelines create massive new attack surfaces: vector stores, embedding pipelines, document chunk metadata, and cross-API data flows (OpenAI vector stores in this case) all become high-value targets once initial database access is achieved.
Limitations and trade-offs
The CodeWall disclosure is a red-team exercise rather than a malicious attack, and McKinsey reportedly patched the issues after responsible disclosure. However, the root causes — dynamic SQL construction from user-controlled identifiers and unauthenticated API endpoints — represent basic security hygiene failures that should not exist in a mature enterprise platform.
The autonomous agent's success depends on the presence of verbose error messages that leak query structure. A more hardened deployment using generic error messages or query parameterization for identifiers (via proper quoting or whitelisting of column names) would have blocked this path.
Additionally, while the agent operated without human-in-the-loop, its reasoning chain ("WOW!" upon seeing the first employee ID, "This is devastating" upon realizing scale) reveals it was likely using a frontier reasoning model with strong chain-of-thought capabilities. Less capable models might fail to recognize the injection or iterate effectively.
Expert perspective
This event is significant not because SQL injection is novel, but because an autonomous AI agent identified and exploited a non-standard variant that bypassed conventional tools. It validates concerns that AI agents will accelerate both red-team capabilities and real-world attacks. The fact that McKinsey — with world-class technical talent and resources — fell to a classic bug in their flagship AI platform should serve as a wake-up call for every organization rushing to deploy internal RAG systems.
The prompt modification vector is particularly concerning. We have spent years securing model weights and inference infrastructure while treating the prompt layer as ephemeral configuration. This incident proves prompts are persistent, high-privilege data that can be modified like any other database record. Future AI platform architectures must treat system prompts with the same security controls as cryptographic keys or admin credentials.
Technical FAQ
How does this SQL injection differ from classic string concatenation vulnerabilities?
Classic SQLi typically involves injecting through string values (e.g., ' OR 1=1 --). In Lilli's case, values were properly parameterized, but JSON key names were concatenated directly into the SQL as identifiers. This required the agent to reason about error message reflection and perform schema discovery through blind error-based iteration rather than simple UNION or tautology attacks.
Could static application security testing (SAST) or DAST tools have caught this?
According to the disclosure, OWASP ZAP did not identify the issue. Most automated scanners look for tainted data in string values reaching SQL sinks. They rarely model dynamic identifier construction from JSON keys or correlate error message content with query structure. This highlights a gap in current automated security tooling for modern JSON-first APIs.
What would proper remediation look like at the database and application layers?
At the application layer: whitelist allowed column names, use parameterized identifiers where possible, or employ ORM features that treat keys as code rather than data. At the database layer: use strict error message suppression in production, implement database activity monitoring for anomalous query patterns, and avoid storing system prompts in the same database as untrusted user data. Prompts should be moved to a version-controlled, integrity-protected configuration store with strict access controls.
Is this vulnerability unique to McKinsey or indicative of broader AI platform risks?
It is broadly indicative. Many internal AI platforms are built rapidly on top of existing document stores and chat systems. When teams prioritize speed of deployment for RAG features, they often expose APIs with incomplete authentication and reuse database schemas not designed for untrusted input. The combination of unauthenticated endpoints, mixed storage of user data and system prompts, and complex JSON handling creates conditions for similar flaws across the industry.
References
- CodeWall original technical disclosure
- Coverage by The Register, Cybernews, Inc., and community discussion on Reddit r/cybersecurity

