Code injection vulnerability

This is a question about the Code injection vulnerability Code Injection | OWASP Foundation
Is there a possibility that if code is stored in a node or relationship property then that code can be used for malicious reasons, like deleting the database or deleting files on the neo4j cluster file system?
Is this prevented by the Cypher execution engine? If not how should applications handle this?
The code can be in any programming language syntax.


It's a good question. Let's explore it.

All nodes and relationships in Neo4j are pure data. The Cypher execution engine (and the language itself) has no support for "evaluation" of the properties within a node or relationship.

Using the Neo4j Browser client application, there is a :param command which can set a query parameter as the result of a query.

So you could do something like:

:param [attack] => {RETURN "MATCH (n) DETACH DELETE n" as attack}

Which would set the query parameter named $attack to the text of a Cypher statement which deletes all data.

However, the query parameter is just a string. There is no way to pass it into a Cypher statement to have it evaluated.

For example, the string can be used like this:

MATCH (n) WHERE n.src = $attack RETURN n

But this doesn't work:

CALL { $attack }

A user would need to use the APOC library to run the cypher:

CALL apoc.cypher.doIt($attack, {});

That could all be combined into a single multi-statement script like this:

CREATE (n:Attack {src:"MATCH (n) DETACH DELETE n"});
:param [attack] => { MATCH (n:Attack) RETURN n.src as attack };
CALL apoc.cypher.doIt($attack, {});

This is a client side sequence that is executed by Neo4j Browser. Not quite code injection. You'd have to trick a user into loading that into Browser, at which point you might as well just have them directly run the malicious Cypher.

Anyone else have other thoughts about how to attack Neo4 with a code injection? What else can we try?


1 Like

ABK, have you seen this?

That article found an application where the query was created by string appending...which is NOT recommended, as it allows this vulnerability. This is why we emphasize using parameters for security (note that in that article the number is NOT handled as a Cypher parameter, thus it is vulnerable).

If the query was handled so inputs were provided as parameters, and not string-appended into the query, then there would be no vulnerability to exploit, as submitted parameter values cannot be interpreted as part of the Cypher query itself, just as a value.

I have a knowledge base article pending release that addresses all of this, I'll post it when it's available.

If you're properly parameterizing your inputs, then the only injection vulnerabilities you would need to worry about are for queries that are using string appending into a query string to be executed dynamically via certain APOC Procedures...and even then, there are ways to design even these queries to use parameters in most contexts.

The tl;dr version:

String appending to a query is always vulnerable, regardless of query language, DON'T EVER DO THIS.

Usage of parameters prevents Cypher injection in nearly all cases, except where dynamic Cypher is string-appended and executed in the query via certain APOC procedures.

1 Like

The knowledge base article on Cypher injection is up, please take a look:

Edited to use the public-facing article.