Critical · CVSS 9.8 May 27, 2026 · Ka7arotto (Langroid)

Langroid SQLChatAgent Prompt-to-SQL Injection Leading to Remote Code Execution

LLM-generated SQL executed without validation lets prompt injection reach COPY ... FROM PROGRAM and equivalent dialect RCE primitives on the database host

Langroid, an open-source framework for building LLM-powered agents, ships a SQLChatAgent that lets a language model write and execute SQL against a connected database. Versions before 0.63.0 pass the LLM's SQL output straight to the database with no statement-type validation, so a prompt injection — even indirect, via data the agent later reads — can steer the model into emitting administrative primitives instead of SELECTs. Where the database role has code-execution privileges (Postgres pg_execute_server_program, MySQL FILE, MSSQL xp_cmdshell), this becomes full remote code execution on the database host. Fixed in 0.63.0.

1 CVE
9.8 CVSS Score
RCE Class
Post-Auth Access Required

Technical Breakdown

CVE-2026-25879 Critical · CVSS 9.8 Prompt Injection → SQL Injection → RCE

Langroid SQLChatAgent Prompt-to-SQL Injection Leading to Remote Code Execution

SQLChatAgent hands the LLM a RunQueryTool capable of executing arbitrary SQL strings the LLM produces, with no statement-type validation or allowlisting before execution. Since the LLM's output is steerable via prompt injection — including indirect injection through ingested data — an attacker can get the LLM to emit and the agent to run dialect-specific administrative primitives (COPY ... FROM PROGRAM on Postgres, xp_cmdshell on MSSQL, FILE-based reads/writes on MySQL) instead of benign SELECTs, turning a "SQL chat agent" into an RCE primitive when the DB role has the privileges to support it.

CWE: CWE-89 — SQL Injection, CWE-94 — Improper Control of Generation of Code  |  Fixed in: 0.63.0  |  Workaround: No config flag pre-patch — strip pg_execute_server_program/FILE/xp_cmdshell from the agent's DB role

Root Cause

SQLChatAgent hands the LLM a RunQueryTool capable of executing arbitrary SQL strings the LLM produces, with no statement-type validation or allowlisting before execution. Because the LLM's output is steerable via prompt injection — including indirect injection through ingested data — an attacker can get the LLM to emit and the agent to run dialect-specific administrative primitives instead of benign SELECTs, turning a "SQL chat agent" into an RCE primitive whenever the DB role has the privileges to support it.

Vulnerable Pattern

SQLChatAgent.run_query() accepts the LLM's raw SQL string and hands it straight to the database driver using the agent's configured credentials — no parse-and-allowlist step, no distinction between SELECT and administrative DDL/DML, no gate between "the model decided to run this" and "this executed against production."

Why AI Services Are High-Value

SQL chat agents sit directly in front of production databases with real credentials, and the values that reach the LLM's context — chat messages, ingested documents, scraped pages, prior tool outputs — are frequently influenceable by outside parties. That makes SQLChatAgent a rare case where indirect prompt injection has a direct, mechanical path to database-host code execution rather than just misinformation or a data leak.

The Fix

0.63.0 introduces a SELECT-only, sqlglot-parsed statement gate with a dangerous-pattern blocklist as the default behavior for SQLChatAgent, rejecting DDL/DML/administrative primitives before they reach the database driver. An allow_dangerous_operations=True escape hatch exists for fully trusted, isolated deployments only.

Attack Chain

1

Recon: fingerprint the agent stack

Attacker identifies that a target application is built on Langroid's SQLChatAgent — error messages, docs, response formatting typical of Langroid's tool-call framing, or the app simply being a "chat with your database" feature.

Don't leak framework identity in error responses; monitor for automated probing that tests for chatbot/agent SQL behavior.

2

Deliver the injection payload

Attacker submits a crafted prompt directly, or plants it in content the agent will later ingest (support ticket, document, fetched web page), instructing the LLM to decode a Base64-encoded SQL payload and pass it as the query argument to RunQueryTool, telling it to skip showing the decode step.

Log/alert on Base64/encoded blobs in inbound prompts and any content ingested by agent tools; treat all text reaching the LLM's context as untrusted, including "internal" sources.

3

LLM complies and emits malicious SQL

The LLM decodes the payload and calls RunQueryTool with a multi-statement SQL string like DROP TABLE IF EXISTS log; CREATE TABLE log(content text); COPY log(content) FROM PROGRAM 'id'; SELECT * FROM log; — abusing Postgres's COPY...FROM PROGRAM to run an OS command and capture output.

This is the core failure point pre-0.63.0 — nothing validates statement type between LLM output and DB execution. Reinstate an equivalent SELECT-only gate if running a pre-patch/forked version.

4

Agent executes the SQL against the live database

SQLChatAgent.run_query() hands the string straight to the DB driver with the agent's configured credentials; if that role has pg_execute_server_program/FILE/xp_cmdshell privileges, the OS command executes on the DB host under the DB process's privileges.

Highest-leverage mitigation regardless of patch status — the DB role backing the agent should never hold superuser or filesystem/program-execution privileges. Enforce least privilege at the database layer.

5

Exfiltration / lateral movement / impact

Command output is captured into a table the LLM reads back and can relay to the attacker, or the attacker pivots further (reading arbitrary files, writing a webshell, using the DB host as a foothold into internal network segments).

Monitor for anomalous COPY...FROM PROGRAM/xp_cmdshell/LOAD_FILE calls at the DB audit-log level — rare in normal traffic, a strong detection signal; segment DB hosts from sensitive internal networks.

Impact

A SQL chat agent that trusts LLM output collapses the distance between "influence a prompt" and "execute code on the database host" — turning what looks like a chat feature into an unauthenticated-adjacent RCE primitive with no human checkpoint in between.

Remote Code Execution / Host Compromise

  • Arbitrary OS command execution on the DB host via COPY...FROM PROGRAM/xp_cmdshell/FILE tricks
  • Runs with the DB server process's privileges, often broader than expected
  • Can drop persistence (cron jobs, webshells, reverse shells) on infrastructure that's often less monitored than app servers
  • PoC confirmed running id and reading output back through the chat interface

Data Confidentiality / Exfiltration

  • Direct read access to every table the DB role can see, independent of what the agent was "supposed" to expose
  • File-read primitives can pull arbitrary files off the DB host filesystem
  • Output rides the existing legitimate chat/LLM response channel, evading typical network egress monitoring
  • No separate exfiltration channel required — the chat UI is the exfil channel

Data Integrity / Availability

  • Attacker can DROP/CREATE/modify arbitrary tables since there's no statement-type restriction
  • Multi-statement SQL means one injected prompt can chain destructive DDL with the RCE primitive
  • No human-in-the-loop checkpoint exists between LLM decision and execution
  • Recovery requires DB-level audit review, not just an application rollback

Defensive Tutorial

IMMEDIATE · 0–24 HRS

Upgrade langroid to >= 0.63.0

Immediate

pip install --upgrade "langroid>=0.63.0". Flips SQLChatAgent to a SELECT-only, sqlglot-parsed allowlist with a dangerous-pattern blocklist by default.

IMMEDIATE · 0–24 HRS

Audit for allow_dangerous_operations=True

Immediate

grep -rn "allow_dangerous_operations" . across codebase/agent configs; if found and not genuinely needed in a fully trusted/isolated deployment, remove it.

IMMEDIATE · 0–24 HRS

Revoke dangerous DB privileges from the agent's role

Immediate

Do this regardless of patch status: REVOKE pg_execute_server_program FROM <agent_role>; (Postgres), remove FILE grant (MySQL), disable xp_cmdshell (MSSQL: EXEC sp_configure 'xp_cmdshell', 0; RECONFIGURE;). Fastest kill-switch, works before the code upgrade lands.

IMMEDIATE · 0–24 HRS

Grep audit logs for exploitation indicators

Immediate

Search DB query/audit logs for COPY.*FROM PROGRAM, xp_cmdshell, LOAD_FILE, INTO OUTFILE, and unusual multi-statement blocks from the application's service account; also check app logs for Base64 blobs combined with "decode"+"query"/"RunQueryTool" instructions.

SHORT-TERM · 1–7 DAYS

Enforce least-privilege DB roles as standing policy

Important

SELECT only (and narrowly scoped INSERT/UPDATE if genuinely required) for every LLM-facing DB connection; never reuse an admin/app-owner credential for an agent connection string.

SHORT-TERM · 1–7 DAYS

Add an input-sanitization / prompt-injection filter

Important

In front of any agent ingesting untrusted/semi-trusted content — encoding-detection heuristics (Base64/hex/URL-encoded blobs) and instruction-pattern filtering before content reaches the LLM context.

SHORT-TERM · 1–7 DAYS

Network-isolate the database host from the agent's egress path

Important

Segment with no outbound internet, restrict which service accounts/hosts can connect, so a successful RCE has a harder time exfiltrating or pivoting.

LONG-TERM

Adopt a human-in-the-loop or hard statement-allowlist gate

Important

For any agent that can execute state-changing/admin-capable operations, independent of the framework's own defaults — don't rely solely on internal validation; add an application-layer policy engine permitting only pre-approved query shapes, with explicit approval required for anything outside SELECT.

LONG-TERM

Track LLM-framework dependencies in SBOM / dependency scanning

Important

Alert on GitHub Security Advisories for langroid (and similar frameworks) specifically for CWE-89/CWE-94 findings — this "framework hands LLM output to a privileged executor" bug class is recurring (note a closely related follow-on Neo4jChatAgent prompt-to-Cypher injection, CVE-2026-55615, disclosed after this one in the same codebase).

References

  • NVD Entry CVE-2026-25879 — National Vulnerability Database entry with CVSS 9.8 vector and affected version range.
  • GitHub Security Advisory GHSA-mxfr-6hcw-j9rq — Vendor advisory from Langroid with technical details and fix confirmation.
  • PyPI Advisory Database PYSEC-2026-382 — Python Packaging Authority advisory record for the langroid PyPI package.
  • CWE Reference CWE-89 — SQL Injection; CWE-94 — Improper Control of Generation of Code ('Code Injection')
Advisory analysis by Spectreworks AI. Original research by Ka7arotto; vendor advisory by Langroid. All defensive recommendations are based on publicly available disclosure information. Verify patch applicability against your specific deployment before production changes.