#40004 [W&A-Critical] Multiple vulnerabilities in signature verification during receipt processing on the archiver server
Was this helpful?
Was this helpful?
Submitted on Feb 12th 2025 at 15:21:19 UTC by @periniondon630 for
Report ID: #40004
Report Type: Websites and Applications
Report severity: Critical
Target: https://github.com/shardeum/archive-server/tree/itn4
Impacts:
Direct theft of user funds
Multiple vulnerabilities in receipt signature verification allow an attacker with an active node connected to the archiver to modify any account balance.
There are two vulnerabilities in the receipt signature verification process on the archiver side. While I couldn't find a way to exploit them independently, combining them results in a critical impact.
The first issue is in the verifyAppliedReceiptSignatures
function:
The function verifies the first requiredSignatures
entries and stores valid signatures in a Map
, using the owner
field (the signer's public key) as the key. However, the owner
field is case-sensitive, which allows an attacker to exploit this by:
Using a single key pair to generate a valid signature.
Cloning the same signature multiple times while modifying the letter case in the owner
field.
Ensuring that all forged signatures appear at the beginning of the signaturePack
list.
Since there are no checks for whether the key belongs to a legitimate node or whether it corresponds to an execution shard, an attacker can effectively bypass proper verification.
The second issue is in the verifyReceiptData
function:
This function performs two checks:
Node existence validation – Ensures that the owner
field corresponds to a node in cycleShardData.nodes
.
Execution group check – Ensures that the node is part of the execution group for the transaction.
However, no actual signature verification is performed. The function only checks whether the owner
field exists in the execution group, meaning an attacker can:
Extract a valid list of nodes from the execution group.
Generate completely fake signatures with their owner
fields set to any valid execution group node.
Include a mix of valid and fake signatures in the signaturePack
, ensuring that any invalid entries are simply skipped without triggering an error.
By carefully crafting the signaturePack
, the attacker can pass both verification steps without having any legitimate signatures.
By combining these vulnerabilities, an attacker can:
Forge any receipt.
Bypass signature verification on the archiver side.
Update any account balance or state without proper authorization.
This effectively allows an attacker with an active node connected to the archiver to manipulate account balances at will.
https://github.com/shardeum/archiver/blob/a55860da3416ca0433579f0e180629d18c9e4c09/src/Data/Collector.ts#L823 https://github.com/shardeum/archiver/blob/a55860da3416ca0433579f0e180629d18c9e4c09/src/Data/Collector.ts#L574
https://gist.github.com/periniondon630/15e3e6a880072e7947696fa69c9fd587
To reproduce the exploit, follow these steps:
Apply the Patch
Apply the patch from the provided Gist to the core repository to enable testing.
Start the Local Network
Launch a local test network and wait until it reaches the processing state.
Start the RPC server.
Create a Coin Transfer Transaction
Send any coin transfer transaction to the network.
Check the Account State on the Archiver
Access the archiver node.
Open the accounts
database using SQLite.
Verify that the targeted account balance has been updated, even though the transaction was not properly signed.
Verify the Forged Receipt in Validator Logs
Check the logs of a connected validator.
Find the receipt that was sent to the archiver.
Confirm that it contains:
Fake signatures from nodes in the execution group.
Cloned signatures from the attacker's node.