Security implications of using pseudorandom JSON-RPC IDs

124 views
Skip to first unread message

Ali Sherief

unread,
Apr 7, 2024, 2:19:08 AMApr 7
to Bitcoin Development Mailing List
I am trying to figure out how the Bitcoin Core RPC server stores the UniValue JSON-RPC requests.

The reason being is because I have an application that uses pseudorandom IDs for the JSON-RPC calls, and I'm trying to make sure that Core isn't going to send me someone else's JSON-RPC response if somebody else happens to be making a request with that ID at the same instant, which could be a potential security issue.

So far I don't have any leads on the Github codebase yet, but I'm still looking.

Anyway I would appreciate if someone would clarify this topic for me.

---
Ali

Ali Sherief

unread,
Apr 7, 2024, 4:28:26 AMApr 7
to bitco...@googlegroups.com

I think the conversation did not get sent to the mailing list somehow. Still trying to get the hang of Google Groups I guess. Anyway I'm going to forward it here just to be sure.

---
Ali
------- Forwarded Message -------
From: Ali Sherief <a...@notatether.com>
Date: On Sunday, April 7th, 2024 at 7:47 AM
Subject: Re: [bitcoindev] Security implications of using pseudorandom JSON-RPC IDs
To: hashnoncemessage <hashnonc...@proton.me>

Using the RPC method 'getrpcinfo', I can't seem to produce a parallel RPC evaluation, even though I am using 4 RPC threads.

If anyone wants to reproduce, you can simulate asynchronous calls in Bash or another shell:

bitcoin-cli getblockchaininfo &
bitcoin-cli getrpcinfo

The output of the second command on my machine is:

{
  "active_commands": [
    {
      "method": "getrpcinfo",
      "duration": 58
    }
  ],
  "logpath": "/home/zenulabidin/.bitcoin/debug.log"
}

I see that there is a global work queue shared by all the threads from which they get the RPC request from: (https://github.com/bitcoin/bitcoin/blob/0f0e36de5f53f82d31416dc05a24d2885781ce57/src/httpserver.cpp#L70-L125

So as I understand it, the system doesn't actually make use of the JSON-RPC metadata such as id, but it's just distributing the work in the queue to different threads. So it is not possible to use the id to corrupt the work queue.

However, what I did notice is that the internal evhttp_request variables can (theoretically) be edited to resolve to a different pointer in order to achieve the same effect, of receiving a different JSON reply. This would require some form of memory corruption bug to be found in Bitcoin Core that affects some global data structure that comes close enough before g_work_queue or the queue itself, so for linux-gcc on x86 platforms at least, any of these variables: (https://github.com/bitcoin/bitcoin/blob/0f0e36de5f53f82d31416dc05a24d2885781ce57/src/httpserver.cpp#L141-L147)

But it would be more likely to cause a node crash than the intended result, I think.

Obviously I'm not a security researcher but I do have a good grasp of C++, so just doing my due diligence to check what kind of attack vectors exist in my program's dependencies.

---
Ali

On Sunday, April 7th, 2024 at 6:33 AM, hashnoncemessage <hashnonc...@proton.me> wrote:
As I understand it, the json rpc server responds directly to the (http) request initiated by the client. 

Request IDs are used for correlation of different requests from the same client. 

Core will not send your client’s response to a different client/connection. 
--
You received this message because you are subscribed to the Google Groups "Bitcoin Development Mailing List" group.
To unsubscribe from this group and stop receiving emails from it, send an email to bitcoindev+...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/bitcoindev/a358aaac-62d5-4d30-a599-40c94da66c4fn%40googlegroups.com.


Antoine Riard

unread,
Apr 9, 2024, 8:28:45 PMApr 9
to Bitcoin Development Mailing List
Hi Ali,

Bitcoin Core RPC protocol as documented in `src/rpc/protocol` RPCErrorCode does not commit to unique JSON RPC IDs towards applications.

About metadata ids, Bitcoin Core's `WorkQueue` only knows about `std::unique_ptr` which is a pointer itself, and as such should have a unique virtual memory address assigned by your kernel to  your `bitcoind` process. While indeed memory corruption *could* lead to resolve a RPC call pointer to another address of a `bitcoind`'s function,
this is dependent on the binary compilation flags, among other things. 

In the future, if you find memory corruption bugs in Bitcoin Core, even benign in non-significant subsystems,  thanks to communicate them with sufficient technical description to secu...@bitcoincore.org or security reporters you trust. If you don't have experience in security handling disclosure, you can consult https://bitcoinops.org/en/topics/responsible-disclosures/ or Linux's https://docs.kernel.org/process/security-bugs.html#securitybugs

Generally, I'll discourage to have multiple user-level applications sharing a common Bitcoin Core JSON-RPC on a single process instance, as soon as you have funds at stake, and when it''s not only for informational purpose like knowing chain state height (e.g block explorer) or features set available. There is no end-to-end encryption of
the JSON RPC calls from user with corresponding key distribution protocol for endpoints. See `doc/JSON-RPC-interface.md` for more.

Best,
Antoine
Reply all
Reply to author
Forward
0 new messages