Audit report AR-27
Reported privately in an independent security review, 2026-08-26.
- Report date
- 2026-08-26
- Kind
- Hardening
- Status on master
- Fixed in bitcoin#36088, bitcoin#36093
- Proposed issue state
- Closed
Summary
Bitcoin Core's IPC code sends UniValue values as JSON text and ignored the result of parsing it on arrival, so malformed JSON from a client reached the implementation as null instead of failing the call. The report is correct and treats it as input-integrity hardening with no demonstrated impact. Already fixed in Bitcoin Core by bitcoin#36088 (merged the day the report was written), with an IPC regression test added in bitcoin#36093.
The report
Bitcoin Core serializes UniValue parameters over IPC as JSON text. The shared read hook, CustomReadField(TypeList<UniValue>) in src/ipc/capnp/common-types.h, called value.read(...) and ignored the boolean it returns, so malformed text left the value null and the receiving implementation was still called. A raw IPC request test confirmed that valid JSON round-trips, while the text not-json is accepted and delivered as null.
The report classes this as local input-boundary integrity hardening, below Bitcoin Core's lowest vulnerability category. The node must be started with the non-default -ipcbind, the caller needs access to its Unix socket, and that socket already grants unauthenticated RPC access. It demonstrated no extra authority, funds, persistence, memory-safety, consensus or availability impact, and found no method where a null argument grants anything extra.
The reproduction is a unit test added to src/ipc/test/ipc_tests.cpp, run against the real IPC code, that sends malformed JSON in a UniValue field.
Proposed change
Check the parser result and throw before calling the implementation; the generated IPC code returns the exception to the client as a failed call:
return read_dest.update([&](auto& value) {
auto data = input.get();
- value.read(std::string_view{data.begin(), data.size()});
+ if (!value.read(std::string_view{data.begin(), data.size()})) {
+ throw std::runtime_error{"Invalid UniValue JSON received over IPC"};
+ }
});
The schema and the handling of valid values are unchanged.
Assessment
Correct, and fixed upstream independently. On Bitcoin Core master the same function now throws "invalid JSON received over IPC" when parsing fails. bitcoin#36088 ("util: Set Univalue to null after read failure", merged 2026-08-26) made UniValue::read leave the value null on failure and added this check; bitcoin#36093 (merged 2026-09-14) added the IPC regression test. The report was withdrawn once the upstream fix was merged.
No stability effect: a null argument makes the RPC or method fail in the normal way. Outside the survey's scope, with no bug page.
Related input-validation report: AR-10 (enum values read without a range check). A protocol fuzz target (AR-06) would exercise this kind of path.
Status
Fixed on Bitcoin Core master by bitcoin#36088 and bitcoin#36093. No further action.
Reported privately in an independent security review on 2026-08-26.