#40007 [BC-Critical] Drain node staking account due to improper validation of SetCertTime internal transaction
Was this helpful?
Was this helpful?
Submitted on Feb 12th 2025 at 16:57:21 UTC by @periniondon630 for
Report ID: #40007
Report Type: Blockchain/DLT
Report severity: Critical
Target: https://github.com/shardeum/shardeum/tree/bugbounty
Impacts:
Direct loss of funds
An attacker can bypass full validation of the SetCertTime transaction and drain the node's staking account balance.
The validateTxnFields
function, responsible for validating transactions, relies on the isSetCertTimeTx
function to enforce full validation on SetCertTime internal transactions. However, an attacker can bypass this validation by exploiting a condition in isSetCertTimeTx
:
The applySetCertTime
function is executed through applyInternalTx
, which is triggered when isInternalTx
returns true
:
As seen in the last condition, isInternalTx
can still return true
even if tx.isInternalTx
is false
, as long as tx.tx.isInternalTx
is true
. This loophole allows an attacker to craft a SetCertTime transaction that:
Bypasses full validation, including signature verification of the proper nominee.
Is processed successfully even though it lacks legitimate authorization.
By repeatedly submitting the forged SetCertTime transaction, the attacker can:
Avoid proper validation while still being processed as an internal transaction.
Incur transaction fees with each execution, leading to a gradual depletion of the node’s staking account balance.
Since constant fees are applied every time this transaction is executed, the attacker can systematically drain the staking balance over multiple iterations.
https://github.com/shardeum/shardeum/blob/167e48478403918468410dd7562929653d5b9f6b/src/setup/validateTxnFields.ts#L79
https://gist.github.com/periniondon630/d2090cae2e9888feff9c8b156bac406a
To reproduce the exploit, follow these steps:
Apply the Bug Bounty Patch
Apply the bug bounty patch for the attacker's node from the audit competition documentation.
Start the Local Network
Launch a local test network and wait until it reaches the processing state.
Stake the Nodes
Stake the nodes as required for normal network operation.
Run the Exploit Script
Execute poc.js
from the provided Gist, supplying:
The attacker's IP and port.
The victim's IP and port.
Verify the Results
Observe the execution logs and check the staking account balance.
If successful, the victim's staking balance should be drained due to repeated transaction fees.