Neo4j is one of the most popular graph databases out there. Tons of people use it for everything from social graphs to recommendation engines. Many of these deployments rely heavily on APOC, short for “Awesome Procedures on Cypher”, a plugin library that significantly expands Neo4j's capabilities with hundreds of extra procedures and functions.

Back in late 2022, security researchers found a big issue in APOC—specifically in the export procedures. This vulnerability, now tracked as CVE-2022-23532, can allow a user to create files *outside* of the allowed export directory. While the bug doesn’t let you overwrite files directly, the ability to *create* new files anywhere you want is bad enough if exploited by someone with the right access.

In this post, I’ll walk you through what the bug is, how it can be exploited, show code examples, direct you to original references, and explain what you can do if your system might be affected.

What Is CVE-2022-23532?

CVE-2022-23532 is a path traversal vulnerability found in the apoc.export.* group of procedures within the APOC plugin for Neo4j. Here’s the problem:

The apoc.export.* procedures let you export data from Neo4j to files.

- Due to improper validation of file paths, someone can trick the procedure into creating files in unintended directories by using things like ../ in the file path.

This could let a malicious user create files wherever the database process can write, like /tmp/evil.txt, /var/log/hack.txt, or even in application directories—though not overwrite current files.

Serious enough if

- An attacker can send Cypher queries to your database (either as a legitimate Neo4j user or by exploiting a Cypher injection flaw in your app).

The database runs with permissions that can write to sensitive areas.

It’s less dangerous than overwriting files— but file creation attacks can still plant dangerous stuff, confuse logs, or set up further exploits.

How Does the Exploit Work?

The attack relies on the way file paths are handled in export procedures, such as apoc.export.csv.query or apoc.export.graphml.all. If you specify a path like ../../outside/export/directory.txt, and the procedure doesn’t clean that up, it will happily create the file *wherever* you pointed.

Simple Exploit Example

Suppose your Neo4j instance runs APOC and you have access to Cypher queries. You could run something like:

CALL apoc.export.csv.query(
  "MATCH (n) RETURN n",
  "../../tmp/evil.csv",
  {}
)


If the system’s export directory is /var/lib/neo4j/import, this query tries to create the file at /var/tmp/evil.csv—*outside* the expected folder. No privilege escalation, but you have just made a new file you shouldn’t be able to.

Who Is Vulnerable?

You are at risk if…
- You run an unpatched Neo4j with APOC plugin accepting arbitrary Cypher queries from untrusted users (including through APIs, bolts, or browser).

Check your version

CALL apoc.help('apoc')


Look for your APOC version in the results.

Official References

- CVE-2022-23532 at NVD
- Neo4j Security Advisory (GitHub)
- APOC Procedures Export Documentation

Mitigations and Workarounds

Upgrade APOC:

Workarounds if you cannot upgrade

1. Restrict procedure use: Control the allowlist of procedures users can call. Limit access to apoc.export.* if not absolutely needed.

This disables exporting to local files entirely.

3. Sanitize Input: If using user-supplied query templates, ensure no one can inject arbitrary file paths.

Conclusion

CVE-2022-23532 is a typical “minor” mistake with potentially big impact. As with many vulnerabilities, it’s only dangerous if attackers can reach the procedure. But if they can, you don’t want people outside your team making files wherever they want.

Regularly audit your Neo4j database configuration and access controls.

If you want a deeper dive or proof of concept, check out the official advisory and patch notes or watch for community write-ups. For most, a version upgrade and conservative permissions should be enough!

Timeline

Published on: 01/14/2023 01:15:00 UTC
Last modified on: 01/24/2023 01:13:00 UTC