Skip to content

bug(graph): read-only Cypher validator rejects valid read queries that mention load, set, update or insert as identifiers #1511

Closed

Description

@Shashankss1205

utils/cypher_readonly.py:6-23, matched as \bKEYWORD\b at :58

The forbidden-keyword list mixes genuine Cypher write clauses with SQL statements Cypher does not have (INSERT, UPDATE, COPY, TRUNCATE, GRANT, REVOKE, ALTER) and with ordinary words that appear constantly as labels, property keys and aliases (LOAD, SET).

Because matching is \bKEYWORD\b over the whole query, any read query that merely mentions one is rejected:

$ .venv/bin/python -c "
from codegraphcontext.utils.cypher_readonly import is_read_only_cypher as r
for q in ['MATCH (n:Module) RETURN n.load ORDER BY n.load',
          'MATCH (n) WHERE n.update > 5 RETURN n',
          'MATCH (n) RETURN n.name AS set',
          'MATCH (n:Insert) RETURN count(n)']:
    print(f'allowed={r(q)}  {q}')
"
allowed=False  MATCH (n:Module) RETURN n.load ORDER BY n.load
allowed=False  MATCH (n) WHERE n.update > 5 RETURN n
allowed=False  MATCH (n) RETURN n.name AS set
allowed=False  MATCH (n:Insert) RETURN count(n)

All four are read-only. n.load is a plausible property on a Module node; AS set is a plausible alias; Insert is a plausible class name in any codebase that models SQL.

Why it matters

execute_cypher_query is the documented expert fallback for agents that need something the typed tools don't cover. Rejecting valid reads pushes the agent into retry loops with no way to phrase the query that works, and the rejection message names keywords the user never wrote as a clause.

Suggested fix

Match write clauses by position rather than bare word presence — a keyword only starts a write when it appears where a clause can begin, not after a . (property access), not after AS (alias), and not as a label/rel-type. Dropping the SQL-only words (INSERT, UPDATE, TRUNCATE, GRANT, REVOKE) costs nothing, since Cypher has no such statements — though note COPY and ALTER are currently asserted in tests/unit/utils/test_cypher_readonly.py:13-14, so that test encodes the present policy and would need revisiting alongside.

Related: #1233 (audit logging for rejections) would make this class of false rejection visible.


Environment
Commit c0e0bed (main)
Python 3.12.3, Linux

Reproduced with the snippet above. Distinct from the literal/comment-ordering bypass fixed in #1508.

Activity

  1. added
    bugSomething isn't working
    severity: mediumIncorrect results, misleading output, or a broken contract
    area: graphDatabase abstraction, Cypher generation, schema, bundles
    on Aug 1, 2026
  2. github-actions commented on Aug 1, 2026

    @github-actions
    Contributor

    Hi! 👋 Join our CodeGraphContext Discord channel to collaborate: https://discord.gg/dR4QY32uYQ

  3. mittalsonal commented on Aug 10, 2026

    @mittalsonal

    Hi @Shashankss1205, I would like to work on this under GSSoC 2026 if it is available.

    Proposed approach:

    • trace the read-only Cypher validation logic that currently rejects identifier text such as load, set, update, or insert
    • tighten the validator so it blocks actual write clauses/keywords while allowing those words when they appear as labels, properties, aliases, or identifiers in read-only queries
    • add focused regression tests for safe read queries using those identifiers plus negative tests for real write operations

    I will wait for formal assignment before coding and keep the PR small, tested, and review-ready.

  4. moved this from Backlog tasks to In progress in CGC Progress Boardon Aug 18, 2026
  5. moved this from In progress to Done in CGC Progress Boardon Aug 18, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

area: graphDatabase abstraction, Cypher generation, schema, bundlesbugSomething isn't workingseverity: mediumIncorrect results, misleading output, or a broken contract

Type

No type

Projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions