The json-rpc service is based on the httpserver module which specifies a TCP connection timeout of HttpHeadersTimeout = 120.seconds. The number of concurrent TCP connections (json-rpc clients) is not restricted which may allow an attacker to effectively open an amount of parallel-persisting connections exhausting the target systems maximum allowed file descriptors.
A malicious entity with access to the json-rpc endpoint may perform a TCP-connection flooding attack in an attempt to force the host system to run out of file descriptors. This may have an affect on file read/writes causing random exceptions or may allow the attacker to impact the target node's peering as no more connections can be opened.
PoC
here's a quick async PoC spawning a lot of parallel connect workers. an attacker may also turn this into a state-less script that does not consume a lot of attacker fd's.
async def connect(target):
while True:
try:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(target)
print(".", end="")
sys.stdout.flush()
return s
except Exception as e:
print(e)
time.sleep(0.1)
continue
async def main(target):
allconns = await asyncio.gather(*[connect(target) for _ in range(10000)])
print("wait 120")
time.sleep(120)
for s in allconns:
if not s:
continue
try:
print("closing")
s.close()
except Exception as e:
print(e)
Mitigation Recommendation
The json-rpc service should be considered as an auxiliary service that is not allowed to impact the nodes chain/validator performance. It is therefore suggested to limit the number of concurrent connections, reduce the service's priority and let it serve on a best-effort basis, and reduce the TCP session timeout which currently is 120 seconds.
Note: this may also affect other services (metrics?)
Note: the json-rpc service should typically not be made publicly available. However, from crawling the eth1/eth2 p2p network we know that RPC services of nodes are often accidentally or purposely made available.
Description
The
json-rpc
service is based on thehttpserver
module which specifies a TCP connection timeout ofHttpHeadersTimeout = 120.seconds
. The number of concurrent TCP connections (json-rpc clients) is not restricted which may allow an attacker to effectively open an amount of parallel-persisting connections exhausting the target systems maximum allowed file descriptors.https://github.com/status-im/nim-json-rpc/blob/6406c96b27b23fc270be03e4f0e4db7412adbb9c/json_rpc/servers/httpserver.nim#L11
Exploit Scenario
A malicious entity with access to the
json-rpc
endpoint may perform a TCP-connection flooding attack in an attempt to force the host system to run out of file descriptors. This may have an affect on file read/writes causing random exceptions or may allow the attacker to impact the target node's peering as no more connections can be opened.PoC
here's a quick async PoC spawning a lot of parallel connect workers. an attacker may also turn this into a state-less script that does not consume a lot of attacker fd's.
Mitigation Recommendation
The
json-rpc
service should be considered as an auxiliary service that is not allowed to impact the nodes chain/validator performance. It is therefore suggested to limit the number of concurrent connections, reduce the service's priority and let it serve on a best-effort basis, and reduce the TCP session timeout which currently is 120 seconds.Note: this may also affect other services (metrics?) Note: the
json-rpc
service should typically not be made publicly available. However, from crawling the eth1/eth2 p2p network we know that RPC services of nodes are often accidentally or purposely made available.