<div dir="ltr">Hi,<br><br>I found a bug in c-lightning which allows a local user to leak near-arbitrary memory through the JSON RPC, which, in the case that the socket is configured to be globally accessible, could allow an attacker to leak sensitive information.<br><br><div>The bug lies in <a href="https://github.com/ElementsProject/lightning/blob/master/common/json.h#L118">the iterator for JSON objects</a>. The code assumes that every key in the json has a corresponding value (that is, every key has a size field >= 1). Now, for valid JSONs, this is clearly true. However, the JSON library used in c-lightning, jsmn, doesn't seem to enforce this, even in strict mode. For example, if jsmn is passed the string '{""""}', it will return a jsmn_tok list that essentially says the JSON has two keys, "" and "", each of size 0 (and thus no corresponding value). While it could be argued that the bug lies with jsmn, similar parsing <a href="https://github.com/zserge/jsmn/issues/158">issues</a> <a href="https://github.com/zserge/jsmn/issues/131">have</a> <a href="https://github.com/zserge/jsmn/issues/117">been</a> <a href="https://github.com/zserge/jsmn/issues/52">mentioned</a> before on their repo but have yet to be fixed despite a rather long time since discovery.<br></div><div><br></div><div>Then, when
<span class="gmail-pl-en">json_for_each_obj is passed the jsmn_tok array, it sees that the JSON object has size 2 (as it has 2 keys), so it iterates over it twice. But in the first iteration, it will already pass over the two valid jsmn_tok values because the size of the key is assumed to be greater than 0. As a result, the next iteration will be out of bounds.</span></div><div><span class="gmail-pl-en"><br></span></div><div><span class="gmail-pl-en">An attacker can manipulate the heap using previous JSON commands to forge jsmn_tok structs. By controlling the start and end values of the token, the attacker can leak arbitrary data relative to the buffer storing the JSON string through <a href="https://github.com/ElementsProject/lightning/blob/master/lightningd/jsonrpc.c#L834">error messages</a>.<br></span></div><div><span class="gmail-pl-en"><br></span></div><div><span class="gmail-pl-en">To replicate this bug, one simply has to pass a JSON such as '{""""}' to the JSON RPC of c-lightning. During my testing, the heap layout was rather inconsistent, so it's probably more reliable to send a JSON with more double quotes such as '{""""""""""""""""""""}' to get a proper segfault (if that doesn't work, keep adding an even number of double quotes).</span></div><div><span class="gmail-pl-en"><br></span></div><div><span class="gmail-pl-en">To fix this, a simple check in the iterator to make sure the size of a jsmn_tok is greater than 0 is likely sufficient to prevent any memory corruption.<br></span></div><div><span class="gmail-pl-en"><br></span></div><div><span class="gmail-pl-en">I hope this was helpful and that the issue gets resolved soon!<br></span></div><div><span class="gmail-pl-en"><br></span></div><div><span class="gmail-pl-en">Sincerely,</span></div><div><span class="gmail-pl-en">Claude Zou<br></span>
</div></div>