#40000 [BC-Critical] Improper input validation in fixDeserializedWrappedEVMAccount leads to DOS and total network shutdown
Was this helpful?
Was this helpful?
Submitted on Feb 12th 2025 at 13:48:37 UTC by @Blockian for
Report ID: #40000
Report Type: Blockchain/DLT
Report severity: Critical
Target: https://github.com/shardeum/shardeum/tree/bugbounty
Impacts:
Network not being able to confirm new transactions (total network shutdown)
This is the same bug that was already submitted in past contests, but was incorrectly fixed: and As stated by you, all past reports expect those stated explicitly are in-scope.
Can be used to crash nodes.
A malicious user legitimately calls the binary/repair_oos_accounts
handler, but with a malicious account data.
The account data is not validated before being passed to fixDeserializedWrappedEVMAccount
, and causes the node to crash
It then iterates its repairInstructions
and extracts data from each instruction
fixAccountUint8Arrays
calls Uint8Array.from
which accepts object with length
field
A malicious user asks a node to sign a staking certificate, also containing fields related to "remove-by-app" or "set-global".
The user then uses that certificate to remove a node or change the global account config, successfully passing signature validation.
Before calling Array.from
validate the type is not an object, everywhere in the code.
This is a total network shutdown which is critical.
In addition, this is the same as the past reports which were critical.
The POC is a combination of the [[#Trigger flow]] from [[#Deep Dive]] to show calculateAccountHash
can be reached by a malicious node, with a POC that shows calculateAccountHash
can be used to crash.
Apply the following changes to shardeum
:
Apply the following changes to core
:
Run a 10 nodes network (shardus start 10
)
Run a json-rpc-server
Run the following attack script:
The fixDeserializedWrappedEVMAccount
, which is commonly used throughout shardeum
repositorie, does not perform validation on the passed data. It is possible to pass an "Array-like" object as the storageRoot
,codeHash
,codeByte
,value
, fields, which is accepted by Uint8Array.from
used by the / functions called from fixDeserializedWrappedEVMAccount
.
binary_repair_oos_accounts
accepts a payload
It then targetNodeId
It then accountId
It then accountData.timestamp
It then txId
It then signedReceipt
with many validations
It then accountData.data
But not before
calls
fixDeserializedWrappedEVMAccount
in the case of AccountType.Account
calls
fixAccountFields
calls