aql_validator
langroid/agent/special/arangodb/aql_validator.py
Security validation for LLM-generated AQL queries (GHSA-2pq5-3q89-j7cc).
ArangoChatAgent executes AQL produced by an LLM, whose text is influenceable
by prompt injection -- directly, or indirectly via content the agent reads back
through RAG. bind_vars only parameterizes values, so the statement text is
the raw LLM string: unrestricted, an attacker who can influence the prompt can
read or destroy all graph data and, where user-defined AQL functions (UDFs),
Foxx, or javascript.allow-admin-execute are enabled on the database role,
escalate toward RCE. This mirrors the prompt-to-SQL-to-RCE issue fixed for
SQLChatAgent in CVE-2026-25879 and the sibling Cypher issue in
Neo4jChatAgent.
Unless the operator opts in with allow_dangerous_operations=True:
- the retrieval (read) path is restricted to read-only AQL -- any data-modification operation (INSERT/UPDATE/REPLACE/REMOVE/UPSERT) is rejected;
- both paths reject user-defined-function calls (
namespace::func), which can run server-side JavaScript.
The checks are keyword/pattern based, applied after stripping comments and string/identifier literals to reduce false positives. A blocklist is inherently bypassable; the real guarantee is the default-off gate plus running the agent against a least-privilege ArangoDB role. Treat this as defense in depth, not a parser-grade allowlist.
validate_aql_query(query, *, is_write, allow_dangerous)
¶
Check an LLM-generated AQL query against the agent's safety policy.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
query
|
str
|
The raw AQL string from the LLM. |
required |
is_write
|
bool
|
True for the creation/write path (data-modification operations are permitted), False for the retrieval/read path (modifications are rejected so the path is read-only). |
required |
allow_dangerous
|
bool
|
When True, skip all checks (operator opt-in). |
required |
Returns:
| Type | Description |
|---|---|
Optional[str]
|
None if the query may be executed, otherwise a human-readable rejection |
Optional[str]
|
message to relay back to the LLM. |