CVEReports
CVEReports

Automated vulnerability intelligence platform. Comprehensive reports for high-severity CVEs generated by AI.

Product

  • Home
  • Sitemap
  • RSS Feed

Company

  • About
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 CVEReports. All rights reserved.

Made with love by Amit Schendel & Alon Barad



CVE-2026-35402
2.3

CVE-2026-35402: Improper Access Control in mcp-neo4j-cypher via Stored Procedure Bypass

Alon Barad
Alon Barad
Software Engineer

Apr 17, 2026·5 min read·5 visits

PoC Available

Executive Summary (TL;DR)

A bypass in mcp-neo4j-cypher's read-only mode allows data modification and SSRF via Cypher stored procedures (CALL) due to an incomplete regex blocklist.

CVE-2026-35402 is an improper access control vulnerability in the mcp-neo4j-cypher server. The application implements a read-only mode using a regex-based keyword blocklist, which fails to restrict execution of Cypher stored procedures via the CALL keyword. This allows authenticated users or LLM agents to bypass restrictions, potentially leading to unauthorized data modification and Server-Side Request Forgery.

Vulnerability Overview

The mcp-neo4j-cypher server functions as a Model Context Protocol (MCP) bridge, enabling Large Language Models to interact directly with Neo4j graph databases. To mitigate the risk of untrusted AI-generated queries modifying the database, the server includes a read_only configuration mode. This mode intends to restrict query execution to data retrieval operations.

The vulnerability, identified as CWE-284 (Improper Access Control), resides in the application's method for enforcing this read-only state. The server employs a fail-open, regular expression-based keyword blocklist. If an incoming query does not contain specific data manipulation language (DML) keywords, the server forwards the query to the backend database.

This implementation fails to account for Cypher's extensibility via stored procedures. By utilizing the CALL keyword, an attacker can invoke backend procedures that manipulate data or interact with the underlying operating system. The application-layer filter ignores the CALL keyword, allowing destructive queries to pass through to the database layer unaffected.

Root Cause Analysis

The root cause of the vulnerability exists in the _is_write_query function within server.py. The application relies entirely on semantic parsing of the query string using a regular expression. The system enforces access control by attempting to identify write-oriented commands, rather than explicitly allowlisting safe read-oriented commands.

The initial regex pattern targeted a static list of explicit DML commands, specifically MERGE, CREATE, SET, DELETE, REMOVE, and ADD. This denylist approach is inherently fragile when applied to complex query languages. Neo4j allows the execution of arbitrary Java code via stored procedures, which bypass query-level semantic checks.

Because the CALL keyword was absent from the regular expression denylist, the application assumes any query beginning with CALL is a read operation. The server subsequently forwards the execution context to the Neo4j database. The procedure then executes with the permissions of the authenticated database user, completely circumventing the intended application-layer restrictions.

Code Analysis

The vulnerable implementation utilizes the Python re.search function to evaluate incoming queries. The code snippet below demonstrates the implementation prior to version 0.5.0. The function returns a boolean value indicating whether the query constitutes a write operation based on strict keyword matching.

def _is_write_query(query: str) -> bool:
    """Check if the query is a write query."""
    return (
        re.search(r"\b(MERGE|CREATE|SET|DELETE|REMOVE|ADD)\b", query, re.IGNORECASE)
        is not None
    )

In version 0.5.0, the developers attempted to patch a related bypass involving the INSERT keyword, which was introduced in modern Cypher syntax. The patch updated the regular expression but failed to address the broader structural flaw regarding stored procedures.

# From Commit 7bf941bb6d9d8cf95d91fd1209b2bf24fdc609d2 (v0.5.0)
- re.search(r"\b(MERGE|CREATE|SET|DELETE|REMOVE|ADD)\b", query, re.IGNORECASE)
+ re.search(r"\b(MERGE|CREATE|INSERT|SET|DELETE|REMOVE|ADD)\b", query, re.IGNORECASE)

Version 0.6.0 resolves the primary bypass by explicitly adding the CALL keyword to the blocklist. Furthermore, the development team transitioned toward protocol-level enforcement. The application now implements RoutingControl.READ within the Neo4j driver for specific administrative procedures, reducing reliance on the regular expression filter.

Exploitation

Exploitation requires an attacker to submit a crafted Cypher query to the mcp-neo4j-cypher endpoint. The target server must operate with the NEO4J_READ_ONLY=true environment variable enabled. The downstream Neo4j database must grant execution permissions to the configured user account.

To perform unauthorized data modification, an attacker leverages standard Neo4j procedures. The query successfully bypasses the application-layer filter because the initial keyword does not trigger the regex check. The database processes the execution block and commits the transaction.

CALL apoc.create.node(['Vulnerable'], {name: 'Exploited'})

If the target environment includes the Awesome Procedures on Cypher (APOC) library, the vulnerability facilitates Server-Side Request Forgery (SSRF). Attackers use network-enabled procedures to retrieve data from adjacent services or internal network interfaces. The following payload demonstrates internal metadata exfiltration.

CALL apoc.load.json("http://169.254.169.254/latest/meta-data/") 
YIELD value RETURN value

Impact Assessment

The primary impact of CVE-2026-35402 is unauthorized data modification within the Neo4j database. Despite explicit configuration requiring read-only behavior, attackers can execute write operations. The scale of the modification is constrained only by the privileges assigned to the database user account utilized by the MCP server.

The secondary impact is internal network exposure via SSRF. The Neo4j database server originates the outbound network requests during procedure execution. This mechanism allows external entities to interact with services located within the database server's internal network segment, bypassing perimeter firewalls.

The assigned CVSS 4.0 score of 2.3 categorizes this vulnerability as Low severity. This rating accounts for the specific prerequisites required for successful exploitation. The attack relies entirely on the target database granting sufficient permissions to the service account and the presence of libraries like APOC to maximize the available attack surface.

Remediation

The immediate remediation requires upgrading the mcp-neo4j-cypher package to version 0.6.0. This release updates the _is_write_query validation logic to identify CALL statements as restricted operations. Administrators must verify the installed version across all application instances connecting to production databases.

Defense-in-depth requires implementing strict Role-Based Access Control (RBAC) at the database layer. Application-layer validation filters are inherently susceptible to bypasses. Administrators must provision a dedicated Neo4j user account for the MCP server and assign it explicitly limited privileges, such as a custom role restricted to TRAVERSE and READ operations.

Environments utilizing the APOC library must implement procedure allowlisting within the database configuration. Modifying the neo4j.conf file to define the dbms.security.procedures.allowlist variable restricts access to high-risk procedures. This database-level control mitigates the SSRF risk regardless of the application's validation logic.

Official Patches

Neo4jGitHub Security Advisory
Neo4jv0.6.0 Release Tag

Fix Analysis (2)

Technical Appendix

CVSS Score
2.3/ 10
CVSS:4.0/AV:N/AC:L/AT:P/PR:L/UI:N/VC:L/VI:L/VA:N/SC:L/SI:L/SA:N

Affected Systems

mcp-neo4j-cypher

Affected Versions Detail

Product
Affected Versions
Fixed Version
mcp-neo4j-cypher
Neo4j
< 0.6.00.6.0
AttributeDetail
CWE IDCWE-284
Attack VectorNetwork
CVSS 4.0 Score2.3
ImpactUnauthorized Data Modification / SSRF
Exploit StatusProof of Concept
CISA KEVNo

MITRE ATT&CK Mapping

T1190Exploit Public-Facing Application
Initial Access
T1550Use Alternate Authentication Material
Defense Evasion
CWE-284
Improper Access Control

Improper Access Control

Vulnerability Timeline

INSERT keyword added to _is_write_query regex in v0.5.0 (Incomplete Fix)
2025-10-30
Vulnerability identified; read_only mode bypass via CALL confirmed
2025-11-03
CVE-2026-35402 and GHSA-x3cv-r3g3-fpg9 published alongside version 0.6.0 release
2026-04-17

References & Sources

  • [1]GitHub Security Advisory GHSA-x3cv-r3g3-fpg9
  • [2]NVD Record for CVE-2026-35402

Attack Flow Diagram

Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.
Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.