#39813 [BC-Critical] Bypass `SetCertTime` transaction signature check #2
Submitted on Feb 8th 2025 at 00:40:28 UTC by @Blockian for Audit Comp | Shardeum: Core III
Report ID: #39813
Report Type: Blockchain/DLT
Report severity: Critical
Target: https://github.com/shardeum/shardeum/tree/bugbounty
Impacts:
Direct loss of funds
Network not being able to confirm new transactions (total network shutdown)
Description
Impact
Bypass the signature of SetCertTime transaction, which allows for draining any validators balance.
Note: same impact as report 33750 but a different root cause.
Root Cause
The function validateSetCertTimeTx validates that the transaction is signed by nominee instead of nominator.
Attack Flow
A malicious user submits a SetCertTime transaction on behalf of someone else (nominator == victim), signing the transaction and setting themselves as nominee, causing a fee to be deducted from the victim's account. The malicious user can then continue doing so until the node is kicked / drained.
Deep Dive
When validating a SetCertTime transaction, the function validateTxnFields which is used to validate transaction fields calls validateSetCertTimeTx which validates properties of the transaction, including its signer's identity:
The problem is that tx.nominee doesn't matter and isn't checked against anything, allowing anyone to set themselves as the nominee and sign an arbitrary SetCertTime transaction.
The fee is then subtracted from the victim's balance in applySetCertTimeTx here, according to the nominator field:
Suggested Fix
Change
to
Severity
This allows to kick validators and do drain funds, and so it critical. In addition, this is the same as 33750 which was classified as critical.
Proof of Concept
POC
All of
shardeum,core, andjson-rpc-servershould be on thebugbountybranchApply
debug-10-nodesas stated in the docsApply the following patch on core (the logs are optional):
Apply the following patch on
shardeum
Run the network with 10 nodes
Wait for all the nodes to be active
Run the following code, to create a staking account:
NOTE: 81d01cb948555a761b6904b3198304593593548c2fcc34407268f61bf8463a8c is the nominee just so an account is created for it.
8. Run the following code, to start draining the staking account:
Was this helpful?