code-423n4 / 2024-05-arbitrum-foundation-findings

1 stars 2 forks source link

L2 sequencer can exploit L3 chains using force inclusion delays #26

Open howlbot-integration[bot] opened 1 month ago

howlbot-integration[bot] commented 1 month ago

Lines of code

https://github.com/code-423n4/2024-05-arbitrum-foundation/blob/main/src/bridge/SequencerInbox.sol#L314 https://github.com/code-423n4/2024-05-arbitrum-foundation/blob/main/src/challengeV2/libraries/ChallengeEdgeLib.sol#L250-L251

Vulnerability details

Cause

The BOLD dispute protocol requires multiple turn-based steps. When deployed on L2 for enabling the L3 use-case, the L2 sequencer can exploit the L3. It can do that by censoring honest validators dispute moves and forcing them to use the L1 force inclusion mechanism. This allows the sequencer to attack or collude with an attacker to create invalid assertions for L3 chains settling to L2. By causing honest L3 validators to use the L1 force inclusion mechanism, the transactions will be included on L2 via L1 with a delay of up to 24 hours for each turn. As the dispute requires many tens of turns (around 50) to complete, these accumulated delays will cause the honest validators to lose.

Impact

The sequencer can submit arbitrary withdrawals and drain any L3 deployed on L2. While generally the sequencer should not be able to cause any safety violations for the sequenced chain, in this case, they can use their limited censorship ability to violate the safety of any L3 by preventing the timely progress of its dispute games.

The dispute requires around 50 turn-based steps from an honest participant, each delayed by possibly up to 24 hours. Because each participant is limited to a 7-day chess clock, honest participants can be forced to lose due to the L1 inclusion delays. This allows the attacker to be able to confirm an arbitrary assertion and prove arbitrary withdrawals from all L3 chains using BOLD on L2.

Notably, even if the maximum or average delay can be reduced, with 50 turn based steps, even if it's shortened to only 4 hours, the 7 day clock will be exhausted by the delays alone. Moreover, even if the average delay can be reduced to even 2 hours, this will leave the honest validators much less time than needed to reliably guarantee the safety of the chain according to the assumptions of the protocol.

L3s BOLD deployments are in scope

While this only is relevant for L3s using BOLD on L2s (Arbitrum itself), and not for L2s using BOLD on L1, the scope of this contest clearly includes the L3 use case:

Q: For an L3 Orbit chain, secured using BOLD, that settles to Arbitrum One, does the one-step proof happen on Arbitrum One? A: Yes

Participant: "And it will be work work layer 3 on arbitrum as well that want a implement the bold mechanism" Sponsor: "yeah that's right"

Severity

Because the sequencer is not trusted with safety with L3s, and is not trusted within the scope of fault proofs, the severity is high. This is not only true due to the trust guarantees, but also due to the intention to decentralize the sequencer role. The loss of funds and trust in the system would be catastrophic, due to the total loss of funds that the L2 sequencer operator is capable of inflicting upon the L3s.

Proof of Concept

As can be seen in the testCanConfirmByOneStep test which runs a challenge from start to finish, if a dishonest assertion is made, the honest validator must complete the full dispute.

Here's a step-by-step scenario for the attack described in the submission:

  1. An L3 chain, called OrbitChain using the BOLD dispute protocol is deployed on Arbitrum (L2).
  2. A malicious L2 (Arbitrum) sequencer operator decides to use its temporary sequencing censorship privileges to create an invalid assertion for the L3 chain.
  3. The attacker submits the invalid assertion to the L2 Rollup chain as an assertion - newStakeOnNewAssertion.
  4. Honest L3 validators recognize the assertion as invalid and attempt to initiate a dispute by calling createLayerZeroEdge to challenge the claim.
  5. The malicious L2 sequencer censors the honest validators' L2 transactions, forcing them to use the L1 force inclusion mechanism to include their transactions on L2. The transactions are included with a significant delay due to the design of the force inclusion delay mechanism. During the delay the attacker's is unrivaled and gains "unrivaled" time.
  6. The attacker responds to the honest validators' dispute without any delay, as their transactions are not censored by the sequencer.
  7. For each level of the dispute (block level, intermediate levels, and SmallStep level), the honest validators and the attacker take turns calling bisectEdge to narrow down the disagreement space.
  8. Due to the L1 force inclusion delay of up to 24 hours for each turn, the honest validators' moves are significantly delayed, while the attacker can respond immediately. During the delay the attacker's is unrivaled and gains "unrivaled" time.
  9. As the dispute progresses through the levels, requiring around 50 turn-based steps, the accumulated delays from the L1 force inclusion mechanism cause the honest validators to exhaust their 7-day chess clock by allowing the attacker to accumulate 7 days of "unrivaled" time.
  10. The honest validators are unable to complete the dispute within the time limit, allowing the attacker's invalid assertion to be confirmed.
  11. The attacker calls confirmEdgeByTime to finish the dispute, and calls confirmAssertion to prove its assertion.
  12. As a result, the invalid assertion is confirmed and added as a root into the outbox, enabling the attacker to submit arbitrary withdrawals and drain funds from the L3 chain.

Tools Used

Manual review.

Recommended Mitigation Steps

The chess-clock and the force-inclusion delay are inherently incompatible with such a long turn-based game if played on L2. In its current highly-interactive form, the application of BOLD should be limited to deployments on L1 (for use in validation of L2s) only, and not for L3s.

Alternatively, two improvements can be made to make the attack less impactful:

  1. Reduce the number of turns to a very small number. This can be done by having each move post all of the data required to challenge any of its components. For example, the levels can be divided into 4 levels such that each level has 2^11 sub-levels (sub-edges) and a call createLayerZeroEdge contains all 2^11 sub levels (how this can be possible is detailed below). This way there are only 2 "turns":
    1. Attacker: createLayerZeroEdge on first level (e.g., level 1) with 2048 sub-levels already detailed on-chain.
    2. Defender: challenge the speciic sub-level - on level 2 already, via createLayerZeroEdge on second level, with all 2048 sub-levels included on-chain.
    3. Attacker: level 3, with all data required for level 4 counter.
    4. Defender: level 4, with all specific instructions.
    5. Attacker: invoke OSP and settle dispute, or wait to lose on time.
  2. Reduce the force inclusion delay to a smaller duration, for example 6 hours.

The combination of these two factors reduce the number of turn-based moves the challenger (defender) needs to make to only 2. If each of those moves is delayed by 6 hours of the force inclusion delay, only 12 hours of the 7 days' clock is lost to the attack, allowing the dispute to proceed with manageable impact.

Posting the required sub-level data would be more expensive for each transaction, but it also reduces the overall amount of transactions and complexity. Additionally on L1, data blobs can be used for this need to make this cheaper. On L2 calldata will be used, which will be posted to L1 blobs, which also make the costs manageable.

In order to store this data on-chain, instead of storing the full data, a merkle root can be calculated and stored from the input data (on-chain). Although merkelization of 2048 would need to be executed on-chain it would be manageable (roughly 4096 hashes) costing around 200K gas. Any subsequent player would be able to construct a proof for any element into the tree from the previously posted data.

Assessed type

Other

godzillaba commented 1 month ago

The force inclusion delay buffer feature prevents this type of repeated censorship by the sequencer.

Picodes commented 1 month ago

From the doc and the whitepaper the 7-day delay is intended for finalization on L1, so to me this is at most a misconfiguration issue, so falls within QA

c4-judge commented 1 month ago

Picodes changed the severity to QA (Quality Assurance)

c4-judge commented 1 month ago

Picodes marked the issue as grade-b