#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

in validateSetCertTimeTx .

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

  1. All of shardeum, core, and json-rpc-server should be on the bugbounty branch

  2. Apply debug-10-nodes as stated in the docs

  3. Apply the following patch on core (the logs are optional):

  1. Apply the following patch on shardeum

  1. Run the network with 10 nodes

  2. Wait for all the nodes to be active

  3. 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?