Skip to content

langroid

v0.65.14 Security

This release includes 1 security fix for security teams reviewing exposed deployments.

✓ No known CVEs patched
Read the diff → Tool health → What is this tool? →
This release patches 1 known CVE

Topics

agents ai chatgpt function-calling llm gpt-4
+10 more
gpt4 information-retrieval language-model llama llm-agent llm-framework local-llm multi-agent-systems openai-api retrieval-augmented-generation

Affected surfaces

auth breaking_upgrade

Summary

AI summary

Updates https://github.com/langroid/langroid/blob/main/SECURITY.md, GHSA-3gpx-vwr3-xvwx, and https://github.com/manus-use across a mixed release.

Full changelog

0.65.14 — SELECT-only really means SELECT-only in SQLChatAgent

SQLChatAgent's statement-type allowlist classified a query by its top-level
parse node alone. Two shapes perform writes without a write node at the top, so
both were accepted as SELECT under the default policy and executed:

  • a data-modifying CTE — WITH x AS (DELETE FROM t RETURNING *) SELECT * FROM x
  • SELECT ... INTO tbl, which creates and populates a table
pip install -U langroid

What was wrong

The allowlist is the control that makes the default configuration safe even
when the agent's database role can write
. That guarantee did not hold: both
shapes parse with a Select top node, so kind resolved to "SELECT",
validation passed, and the statement was executed and committed while the
engine performed the write.

Unlike the dangerous-function denylists, this needed no superuser and no
special extension
— an ordinary write-capable role was enough. Verified
against sqlglot:

writable CTE   top=Select  nested_writes=['Delete']
SELECT INTO    top=Select  into=True

The fix

A new _nested_write_kinds() walks the parsed statement for
Insert/Update/Delete/Merge/Create/Drop/Alter/TruncateTable
nodes below the top level, and separately flags the SELECT ... INTO form.
Any nested kind outside allowed_statement_types is rejected, naming what it
found.

This is a bounded fix rather than another denylist entry: statement kinds are a
closed set, so walking the tree closes the whole class.

Three refinements came out of adversarial review, each with its own regression
test:

  • MERGE actions are exempt. sqlglot parses WHEN MATCHED THEN UPDATE as
    a child Update node, so an operator allowing MERGE would otherwise have
    been forced to allow standalone UPDATE/INSERT as well.
  • …but only the action itself. The exemption matches the WHEN ... THEN
    node by identity. Matching anything beneath a WHEN would have hidden a
    write in the WHEN condition — turning the exemption into a smuggling
    route.
  • MySQL SELECT ... INTO @var is not a table creation. It assigns a user
    variable and writes nothing, but sqlglot models the target as
    Table(this=Parameter(...)); treating it as a write rejected a legitimate
    read. SELECT ... INTO t UNION ALL SELECT ... is now caught too, where the
    into sits on a branch and the top node is a Union.

Behavior otherwise unchanged: read-only CTEs still pass, an operator who
extends allowed_statement_types still gets exactly the writes they
authorized, and allow_dangerous_operations=True still bypasses every check.

Upgrade notes

If you run SQLChatAgent against a write-capable role, upgrade. If your
database role is read-only — the configuration
SECURITY.md
recommends — you were never exposed to this. No API changes.

Scope policy

SECURITY.md was corrected alongside the fix. Allowlist misclassification had
been wrongly grouped with denylist bypasses and declared out of scope; it is a
bounded, fixable defect and is now explicitly in scope. The denylists
themselves remain best-effort hardening, not a security boundary — the real
boundary is the privileges of the database credential you hand the agent, plus
the container and filesystem the process runs in.

Credit

Reported by @manus-use
(GHSA-3gpx-vwr3-xvwx), and earlier by
@LHMisme420 (GHSA-wc83-4cvx-p8xc) — the
earlier report was closed in error and the second one prompted the correction.
The MERGE regression was caught by the GitHub Codex reviewer on
#1074.

Upgrade

pip install -U langroid

Full changelog:
0.65.13...0.65.14

Security Fixes

  • GHSA-3gpx-vwr3-xvwx — SQLChatAgent incorrectly accepted write statements disguised as SELECT (data‑modifying CTEs and SELECT INTO); now rejects them.

Weekly OSS security release digest.

The CVE patches and breaking changes that affected production tools this week. One email, every Sunday.

No spam, unsubscribe anytime.

Share this release

Track langroid

Get notified when new releases ship.

Sign up free

About langroid

Harness LLMs with Multi-Agent Programming

All releases →

Related context

Earlier breaking changes

  • v0.65.9 MCP tool parameters now strictly validate enums, unions, and nested models.
  • v0.65.5 Blocks code‑execution, file, and network primitives in creation tools by default.
  • v0.65.5 Restricts retrieval tools to read‑only queries; write or admin clauses are rejected by default.
  • v0.65.3 Raw user messages containing tools registered with `enable_message(..., use=False, handle=True)` are now dropped instead of executed.
  • v0.65.2 Restricts eval'd expression builtins to a curated safe set, breaking code that relied on full Python builtins (e.g., __import__, open).

Beta — feedback welcome: [email protected]