serialization: validate RingCT prunable JSON type
What changed, and why it matters
This commit adds a type check in Monero's JSON deserialization code. Before the fix, when reading a RingCT signature from JSON, the code assumed the 'prunable' field was a JSON object and accessed it directly. If someone supplied a non-object value (like a number or string), the code could read memory incorrectly or crash. The patch now throws a clear error if the type is wrong.
Treat as a low-to-moderate hardening fix. Backport to maintained branches if JSON RPC endpoints or wallet tools accept rctSig JSON. Review adjacent fromJsonValue functions for similar missing type checks.
Security signals we found
Input validation gap in deserialization path
Potential crash/undefined behavior on malformed JSON
RingCT signature parsing is consensus-adjacent code
Small, targeted hardening patch
Evidence from the diff
In src/serialization/json_object.cpp, fromJsonValue() for rct::rctSig now verifies that the ‘prunable’ member of the incoming rapidjson::Value is IsObject() before using GET_FROM_JSON_OBJECT on it. Without this guard, passing a non-object value (e.g., array, scalar) would lead to rapidjson member lookups on an invalid type, likely causing assertion failures, undefined behavior, or a denial-of-service crash during JSON parsing of transaction-related data.
Changed components
src/serialization/json_object.cpprct::rctSig JSON deserializationRingCT prunable data parsingInspect captured patch +5 / −0
diff --git a/src/serialization/json_object.cpp b/src/serialization/json_object.cpp
index 73ddaea..ad954ee 100644
--- a/src/serialization/json_object.cpp
+++ b/src/serialization/json_object.cpp
@@ -1173,6 +1173,11 @@ void fromJsonValue(const rapidjson::Value& val, rct::rctSig& sig)
const auto prunable = val.FindMember("prunable");
if (prunable != val.MemberEnd())
{
+ if (!prunable->value.IsObject())
+ {
+ throw WRONG_TYPE("json object");
+ }
+
rct::keyV pseudo_outs = std::move(sig.get_pseudo_outs());
GET_FROM_JSON_OBJECT(prunable->value, sig.p.rangeSigs, range_proofs);
Why this scored 47/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.