CVE-2026-50180: langroid: SQL blocklist bypass leaks Postgres files

GHSA-pmch-g965-grmr HIGH
Published July 2, 2026
CISO Take

langroid's SQLChatAgent enforces a SELECT-only allowlist plus a regex blocklist meant to stop dangerous SQL functions, but the blocklist enumerates specific function names and misses the entire pg_read_file/pg_stat_file/pg_ls_logdir/pg_ls_waldir/pg_current_logfile family — so an LLM-generated SELECT using any of them slips straight through to the live SQLAlchemy engine and reads arbitrary files off the PostgreSQL host, including postgresql.conf, pg_hba.conf, and TLS keys. Any agent that lets an LLM shape SQL from untrusted input — a user prompt, a retrieved document, or an upstream API response the agent is asked to summarize — inherits this, and no PostgreSQL credentials are needed since the agent already holds them. There's no CISA KEV listing, no EPSS score, and no public exploit or Nuclei template yet, and package-level exposure looks limited (4 known downstream dependents), but the bug is trivially reproducible and a working fix PR already exists upstream. Patch to langroid 0.64.0, which closes the pg_* family plus the SQLite ATTACH-without-DATABASE-keyword and MSSQL OPENDATASOURCE gaps documented in GHSA-pmch-g965-grmr; if you can't patch immediately, strip pg_read_file/pg_stat_file/pg_ls_*/pg_current_logfile privileges from the DB role your agent uses, since a regex blocklist in application code is not a substitute for least-privilege at the database layer.

Sources: NVD GitHub Advisory ATLAS

What is the risk?

High severity per the advisory, but real-world exposure is currently limited: only 4 known downstream dependents, no CISA KEV listing, no EPSS score, and no public exploit or scanner template observed. That said, exploitability is trivial once an attacker can influence the LLM's SQL generation — no authentication, no special DB privileges, and no complex chaining are required; a single SELECT against a near-miss function name is sufficient. The larger risk is systemic: this is a defense-in-depth control implemented as a hand-maintained function-name blocklist, a pattern known to be brittle (PostgreSQL alone ships several near-name siblings for every blocked function). Any deployment relying solely on `_validate_query` rather than database-level least privilege should be treated as exposed regardless of patch status until DB role permissions are also reviewed.

How does the attack unfold?

Prompt injection
Attacker-controlled content (direct user prompt or data ingested by the agent) shapes the SQL the LLM will generate.
AML.T0051.001
Validator bypass
The LLM emits a SELECT calling a file-disclosure function (e.g. pg_read_file, OPENDATASOURCE, ATTACH without DATABASE) whose name matches no entry in the regex blocklist while still satisfying the SELECT-only allowlist.
AML.T0107
Tool execution
SQLChatAgent.run_query passes the query straight to the live SQLAlchemy engine, which executes it against the production database.
AML.T0053
Data exfiltration
File contents, directory listings, or remote query results are returned in the agent's response and read by the attacker out of the chat transcript.
AML.T0086

What systems are affected?

Package Ecosystem Vulnerable Range Patched
Langroid pip <= 0.63.0 0.64.0
4.1K 4 dependents Pushed 22d ago 100% patched ~14d to patch Full package profile →

Do you use Langroid? You're affected.

How severe is it?

CVSS 3.1
N/A
EPSS
0.6%
chance of exploitation in 30 days
Higher than 45% of all CVEs
Exploitation Status
No known exploitation
Sophistication
Moderate

What should I do?

1 step
  1. Upgrade to langroid >= 0.64.0, which patches _DANGEROUS_SQL_PATTERNS to block the full pg_read*/pg_stat*/pg_ls*/pg_current_logfile family, the SQLite ATTACH-without-DATABASE form, and MSSQL OPENDATASOURCE (fix and regression tests at GHSA-pmch-g965-grmr, commit 00b7dd7). If immediate upgrade isn't possible: (1) revoke pg_read_server_files, superuser, and any filesystem-adjacent role membership from the PostgreSQL role SQLChatAgent connects as — that's the actual control boundary, not the regex; (2) if using SQLite, keep allowed_statement_types restricted to SELECT only and never add ATTACH; (3) if using SQL Server, add an application-level check for OPENDATASOURCE alongside the existing OPENROWSET block. For detection, log and alert on agent-executed SELECT queries referencing pg_read_file, pg_stat_file, pg_ls_logdir, pg_ls_waldir, pg_ls_tmpdir, pg_current_logfile, OPENDATASOURCE, or ATTACH — none of these appear in ordinary text-to-SQL analytics queries.

What does CISA's SSVC say?

Decision Track
Exploitation none
Automatable Yes
Technical Impact partial

Source: CISA Vulnrichment (SSVC v2.0). Decision based on the CISA Coordinator decision tree.

How is it classified?

Which compliance frameworks are affected?

This CVE is relevant to:

EU AI Act
Article 15 - Accuracy, Robustness and Cybersecurity
OWASP LLM Top 10
LLM01 - Prompt Injection LLM06 - Excessive Agency

Frequently Asked Questions

What is CVE-2026-50180?

langroid's SQLChatAgent enforces a SELECT-only allowlist plus a regex blocklist meant to stop dangerous SQL functions, but the blocklist enumerates specific function names and misses the entire pg_read_file/pg_stat_file/pg_ls_logdir/pg_ls_waldir/pg_current_logfile family — so an LLM-generated SELECT using any of them slips straight through to the live SQLAlchemy engine and reads arbitrary files off the PostgreSQL host, including postgresql.conf, pg_hba.conf, and TLS keys. Any agent that lets an LLM shape SQL from untrusted input — a user prompt, a retrieved document, or an upstream API response the agent is asked to summarize — inherits this, and no PostgreSQL credentials are needed since the agent already holds them. There's no CISA KEV listing, no EPSS score, and no public exploit or Nuclei template yet, and package-level exposure looks limited (4 known downstream dependents), but the bug is trivially reproducible and a working fix PR already exists upstream. Patch to langroid 0.64.0, which closes the pg_* family plus the SQLite ATTACH-without-DATABASE-keyword and MSSQL OPENDATASOURCE gaps documented in GHSA-pmch-g965-grmr; if you can't patch immediately, strip pg_read_file/pg_stat_file/pg_ls_*/pg_current_logfile privileges from the DB role your agent uses, since a regex blocklist in application code is not a substitute for least-privilege at the database layer.

Is CVE-2026-50180 actively exploited?

No confirmed active exploitation of CVE-2026-50180 has been reported, but organizations should still patch proactively.

How to fix CVE-2026-50180?

Upgrade to langroid >= 0.64.0, which patches `_DANGEROUS_SQL_PATTERNS` to block the full pg_read*/pg_stat*/pg_ls*/pg_current_logfile family, the SQLite ATTACH-without-DATABASE form, and MSSQL OPENDATASOURCE (fix and regression tests at GHSA-pmch-g965-grmr, commit 00b7dd7). If immediate upgrade isn't possible: (1) revoke `pg_read_server_files`, superuser, and any filesystem-adjacent role membership from the PostgreSQL role SQLChatAgent connects as — that's the actual control boundary, not the regex; (2) if using SQLite, keep `allowed_statement_types` restricted to `SELECT` only and never add `ATTACH`; (3) if using SQL Server, add an application-level check for `OPENDATASOURCE` alongside the existing `OPENROWSET` block. For detection, log and alert on agent-executed `SELECT` queries referencing `pg_read_file`, `pg_stat_file`, `pg_ls_logdir`, `pg_ls_waldir`, `pg_ls_tmpdir`, `pg_current_logfile`, `OPENDATASOURCE`, or `ATTACH` — none of these appear in ordinary text-to-SQL analytics queries.

What systems are affected by CVE-2026-50180?

This vulnerability affects the following AI/ML architecture patterns: agent frameworks, text-to-SQL / data-analyst agents, RAG pipelines.

What is the CVSS score for CVE-2026-50180?

No CVSS score has been assigned yet.

What is the AI security impact?

Affected AI Architectures

agent frameworkstext-to-SQL / data-analyst agentsRAG pipelines

MITRE ATLAS Techniques

AML.T0051.001 Indirect
AML.T0053 AI Agent Tool Invocation
AML.T0086 Exfiltration via AI Agent Tool Invocation
AML.T0107 Exploitation for Defense Evasion

Compliance Controls Affected

EU AI Act: Article 15
OWASP LLM Top 10: LLM01, LLM06

What are the technical details?

Original Advisory

Langroid is a framework for building large-language-model-powered applications. Prior to version 0.64.0, `SQLChatAgent` in `langroid` ships a `_validate_query` defense-in-depth layer whose `_DANGEROUS_SQL_PATTERNS` regex blocklist enumerates dangerous SQL primitives by specific function name. The list misses the canonical PostgreSQL filesystem-disclosure family `pg_read_file()`, `pg_stat_file()`, `pg_ls_logdir()`, `pg_ls_waldir()`, `pg_current_logfile()` (and similar `SELECT`-shaped functions in the same family). It also leaves SQL Server `OPENDATASOURCE` and SQLite `ATTACH '<file>' AS x` (DATABASE keyword omitted) unblocked. An attacker able to shape the LLM's generated SQL (directly via prompt input or transitively via prompt-injection in data the LLM ingests) can read arbitrary files from the PostgreSQL host through ordinary `SELECT` queries, even with the agent's strict default configuration (`allow_dangerous_operations=False`, `allowed_statement_types=['SELECT']`). The payloads survive the statement-type allowlist (each is a `SELECT`) and pass through the regex blocklist (none of the function names match), then reach the live SQLAlchemy engine via `SQLChatAgent.run_query`. Version 0.64.0 contains a patch for the issue.

Exploitation Scenario

A team deploys a langroid SQLChatAgent as an internal data-analyst copilot over a PostgreSQL warehouse, using the documented safe defaults (`allow_dangerous_operations=False`, `allowed_statement_types=['SELECT']`). An attacker — either a direct user of the chat interface, or an external party who plants instructions in a document or web page the agent is later asked to summarize (indirect prompt injection) — gets the LLM to emit `SELECT pg_read_file('../../pg_hba.conf')` or `SELECT pg_current_logfile()` as its generated query. The statement is syntactically a SELECT, so it passes the sqlglot-based statement-type allowlist; its function name isn't among the 17 patterns in `_DANGEROUS_SQL_PATTERNS`, so it also passes the regex blocklist. `SQLChatAgent.run_query` executes it against the live SQLAlchemy engine and returns the file contents (or log/WAL directory listing) straight back into the LLM's response, which the attacker then reads out of the chat transcript — no credentials, no privilege escalation, and no direct database access beyond what the agent already had.

Weaknesses (CWE)

CWE-22 — Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal'): The product uses external input to construct a pathname that is intended to identify a file or directory that is located underneath a restricted parent directory, but the product does not properly neutralize special elements within the pathname that can cause the pathname to resolve to a location that is outside of the restricted directory.

  • [Implementation] Assume all input is malicious. Use an "accept known good" input validation strategy, i.e., use a list of acceptable inputs that strictly conform to specifications. Reject any input that does not strictly conform to specifications, or transform it into something that does. When performing input validation, consider all potentially relevant properties, including length, type of input, the full range of acceptable values, missing or extra inputs, syntax, consistency across related fields, and conformance to business rules. As an example of business rule logic, "boat" may be syntactically valid because it only contains alphanumeric characters, but it is not valid if the input is only expected to contain colors such as "red" or "blue." Do not rely exclusively on looking for malicious or malformed inputs. This is likely to miss at least one undesirable input, especially if the code's environment changes. This can give attackers enough room to bypass the intended validation. However, denylis
  • [Architecture and Design] For any security checks that are performed on the client side, ensure that these checks are duplicated on the server side, in order to avoid CWE-602. Attackers can bypass the client-side checks by modifying values after the checks have been performed, or by changing the client to remove the client-side checks entirely. Then, these modified values would be submitted to the server.

Source: MITRE CWE corpus.

Timeline

Published
July 2, 2026
Last Modified
July 10, 2026
First Seen
July 2, 2026

Related Vulnerabilities