34252 - [BC - Critical] Bypass Certificate Signing Validation
Bypass Certificate Signing Validation
Submitted on Aug 7th 2024 at 21:12:49 UTC by @Blockian for Boost | Shardeum: Core
Report ID: #34252
Report type: Blockchain/DLT
Report severity: Critical
Target: https://github.com/shardeum/shardus-core/tree/dev
Impacts:
Network not being able to confirm new transactions (total network shutdown)
Direct loss of funds
Description
Bypass Certificate Signing Validation
Impact
Bypass stake certificate validation, allowing for non-staking nodes and network take-over
Bypass nodes removal validation, allowing to remove nodes from the network
Root Cause
The function validateClosestActiveNodeSignatures
counts repeated signatures as different signatures, allowing for 1 valid signature to be counted as minRequired
. In other words - signatures are counted, instead of signers.
Deep Dive
The functions validateClosestActiveNodeSignatures
and validateActiveNodeSignatures
receive a parameter minRequired
that specify what is the minimal number of nodes need to sign the appData to make it valid.
https://github.com/shardeum/shardus-core/blob/4d75f797a9d67af7a94dec8860220c4e0f9ade3c/src/shardus/index.ts#L1780
https://github.com/shardeum/shardus-core/blob/4d75f797a9d67af7a94dec8860220c4e0f9ade3c/src/shardus/index.ts#L1746 It does so by looping over the signature list, and checking if the signature is valid. If it is, the counter is incremented.
https://github.com/shardeum/shardus-core/blob/4d75f797a9d67af7a94dec8860220c4e0f9ade3c/src/shardus/index.ts#L1763
https://github.com/shardeum/shardus-core/blob/4d75f797a9d67af7a94dec8860220c4e0f9ade3c/src/shardus/index.ts#L1763 If the amount is more than the min required,
true
is returnedhttps://github.com/shardeum/shardus-core/blob/4d75f797a9d67af7a94dec8860220c4e0f9ade3c/src/shardus/index.ts#L1769
https://github.com/shardeum/shardus-core/blob/4d75f797a9d67af7a94dec8860220c4e0f9ade3c/src/shardus/index.ts#L1815
Suggested Fix
Remove the public key from closestNodesByPubKey
after counting it.
Flow
Malicious node generates a fake
JoinRequest
with a fakeStakingCertificate
It brute-forces
StakingCertificate
fields to make sure its one of the closest nodes to the hash of the staking certificates. This is easy, as only 1 node is needed to be close.
It creates the full JoinRequest, with multiple copies of its signature, instead of signatures from many other nodes.
It calls gossip-join-request
Other nodes receive the join request, and validate it using
validateClosestActiveNodeSignatures
.The validation bypasses, as they count the number of signatures and not the number of signers.
The new node joins the network without staking.
Severity
This allows to take over the network (by kicking nodes / adding nodes) and so it critical.
Proof of concept
POC
Set-up
Clone
shardeum
(dev
branch)Clone
json-rpc-server
(dev
branch)Clone
simple-network-test
(dev
branch)Run
npm i
inside all three directoriesInstall
shardus
according to the readme inshardeum
:
Apply the
debug-10-nodes.patch
with a 5 nodes modification:
Apply the suggested local network changes from the docs:
Prepare the
shardeum
project by running
inside the shardeum
directory.
Start a local network by running
inside the shardeum
directory.
Run a local
json-rpc-server
by running
at the json-rpc-server
directory.
Wait for the network to be ready, by looking at the output from the
json-rpc-server
. We needCurrent number of good nodes
to be 5.Apply the patch for package.json inside
simple-network-test
Create the poc file