QueryShield › Guides

How do I prevent SQL injection from LLM-generated queries?

Text-to-SQL security is a distinct problem from classic parameterized-query hygiene. With an LLM in the loop, the query itself is generated from untrusted natural language, so a prompt injection can steer the model into producing SQL that is syntactically valid but unauthorized, destructive, or data-leaking.

Why escaping is not enough

Parameterization protects individual literals, but the LLM writes the whole statement — table names, joins, and clauses included. The real guardrail is a validation layer that inspects the generated SQL as structure, not text.

What a validation layer should enforce

How prompt injection becomes SQL injection

In classic SQL injection an attacker controls one parameter inside a query a developer wrote. With an LLM, the attacker only needs to get text into the model’s context — a user message, a support ticket, a row the agent read earlier — and the model writes the malicious query itself. That chain has three steps:

  1. untrusted text reaches the prompt;
  2. the model turns it into syntactically valid SQL;
  3. the SQL runs with whatever access the agent holds.

You cannot reliably break step 1 or step 2, because both are probabilistic. Step 3 is where enforcement is deterministic: the query is a concrete artifact you can parse and reject.

Time-based SQL injection through prompt injection

A blind attacker who cannot see query results can still extract data one bit at a time. The injected instruction steers the model into a query like SELECT CASE WHEN (condition) THEN pg_sleep(5) END: if the response is slow, the condition was true. Repeat that across enough conditions and the attacker reconstructs values without a single row being returned.

A read-only role does not stop this, because sleep functions are readable by default. QueryShield rejects pg_sleep, MySQL’s SLEEP and BENCHMARK, and the other deny-listed functions anywhere in the AST — including inside subqueries and CTEs — so the timing channel never opens.

QueryShield applies all of these as a proxy in front of your database, and audit-logs every decision. Because the agent only ever talks to the proxy, it never sees connection strings or credentials to abuse in the first place.

Enforce this automatically with QueryShield

A secure SQL proxy for AI agents: natural language in, SELECT-only validated SQL out, per-agent row-level security, and an append-only audit log. Your agents never see connection strings.

Get an API key — free tier Read the API docs

Related guides