42153 [BC-Critical] attackers can exploit bug in blob verification to execute replay attack by re executing blobs

#42153 [BC-Critical] Attackers can exploit bug in Blob Verification to execute replay attack by re-executing blobs

Submitted on Mar 21st 2025 at 10:40:58 UTC by @perseverance for Attackathon | Movement Labs

  • Report ID: #42153

  • Report Type: Blockchain/DLT

  • Report severity: Critical

  • Target: https://github.com/immunefi-team/attackathon-movement/tree/main/protocol-units/da/movement/protocol/util

  • Impacts:

    • Direct loss of funds

Description

Background Information

Description

Brief/Intro

A critical vulnerability exists in Movement Network's Data Availability (DA) layer where the blob ID verification process is incomplete. The current implementation only verifies the signature against the computed ID but does not verify if the blob ID matches the computed ID. This can lead to potential replay attacks and inconsistent state across the network.

According to the architecture of Movement Network ( https://docs.movementnetwork.xyz/general/Mainnet/high_level_architecture ), the blob data is sent and received from Celesia DA Service.

As Celestia is a public chain, anyone can submit malformed blobs. So verification of Blob Data is very important.

InnerSignedBlobV1 has following structure: https://github.com/immunefi-team/attackathon-movement/blob/main/protocol-units/da/movement/protocol/util/src/blob/ir/blob.rs#L12-L20

When receive blobs from Celestia, the node verify the blobs. This verification is very important to protect from hacks.

The vulnerability

Vulnerability Details

The vulnerability exists in the try_verify function in blob.rs:

https://github.com/immunefi-team/attackathon-movement/blob/main/protocol-units/da/movement/protocol/util/src/blob/ir/blob.rs#L35-L46

Notice that the code compute_id from the data of InnerSignedBlobV1. So the id is computed from the blob data and timestamp digest. The signature is verified against this compute_id

https://github.com/immunefi-team/attackathon-movement/blob/main/protocol-units/da/movement/protocol/util/src/blob/ir/data.rs#L38-L48

But there is no verification that the blob id is matching the compute_id.

So this allows the attack scenario:

An attacker can take a valid blob from Celestia, modify the id, and post it on Celestia again. Such a blob will pass all the verification steps in movement da and end up in the full-node execution task where blob.id is used for de-duplicating the execution. Since the ID is now forged and new, it will be incorrectly re-executed.

https://github.com/immunefi-team/attackathon-movement/blob/main/networks/movement/movement-full-node/src/node/tasks/execute_settle.rs#L100-L138

Is it a known issue or not?

NO.

In my research, this bug is very similar to a closed bug in Movement issues: https://github.com/movementlabsxyz/movement/issues/877

The bug 877 was closed because it was fixed in pull request https://github.com/movementlabsxyz/movement/pull/888

In that pull request, the movement team introduced the compute_id and include the id in the signature to prevent hacks.

But my bug report circumvented this check. Because although the signature is signed on the id, but since in the function process_block_from_da , the signature verification verify the signature with the computed id. But there is no verification of the blob id.

Since this bug is very similar to report 877, so the attack scenario is valid as commented by Movement team in report 877

About the severity assessment

This is assessed as Critical severity because:

Severity : Critical

Impact: Direct loss of funds

Because:

  • Can lead to replay attacks

  • Can lead to Direct loss of funds

  • If the re-execution of blobs result in succesful transactions then it is double spending.

  • if the re-exeuction is failed, then gas of users can be deducted. There is a known issue of not charging for failed transactions https://github.com/movementlabsxyz/movement/issues/409 . But this will be fixed, so anyway the users balance can be deducted.

Likelihood: High

Since an attacker can exploit this and gain profits, so it is highly likely to happen.

Mitigation

In my understanding, the fix requires adding ID verification in the try_verify function.

This ensures both the signature and ID are properly verified before processing the blob.

Proof of Concept

Proof of concept

The vulnerability can be triggered when:

Step 1: Fork a malicious blob from a valid blob with:

  • Valid data and timestamp

  • Valid signature for computed ID

  • Different valid ID than computed ID that computed from data and timestamp

Step 2: Send the malicious blob to Celestia

Step 3. The node will read data from Celestia and will verify the blob

  • Compute ID from data and timestamp

  • Verify signature against computed ID . => This will pass

Expected result: The blob will be re-executed despite having mismatched IDs, demonstrating the vulnerability.

Was this helpful?