Submitted by alexfilippov314, also found by kuprum, 0x1771, Zubat, ether_sky, and Femboys
Large preimage proposals (LPP) allow submitters to prove that certain data is a fixed part of the large preimage that produces a specific Keccak-256 hash value. Since the preimage is large, the process of LPP finalization involves multiple transactions. Because the intermediate steps are not verified on-chain, LPP flow requires a challenge period during which challengers can verify the correctness of the LPP and dispute it on-chain via the challengeLPP and challengeFirstLPP functions.
The issue arises from the fact that the current implementation of the squeezeLPP function allows a malicious submitter to bypass the challenge period and finalize an invalid proposal. Ive provided a detailed description of why it is possible below.
The squeezeLPP function checks that the challenge period is still active using this check:
While it looks correct, the problem here is that the timestamp is not initialized in the initLPP function. If the metadata.timestamp() is zero this check will always succeed (assuming that block.timestamp > CHALLENGE_PERIOD). The only place where metadata.timestamp is set is in the addLeavesLPP function, if the attacker provided a true value for the _finalize argument.
While it may seem logical, the current flow does not require the submitter to provide a true value for the _finalize argument in any of their calls. This fact is demonstrated in the POC below. This means that the submitter can make the necessary number of addLeavesLPP calls with _finalize = false and then call squeezeLPP immediately after (since the metadata.timestamp remains uninitialized), without having to wait for the challenge period to pass. Since there is no challenge period, a malicious submitter can submit invalid proposals without the risk of being challenged.
The full attack is demonstrated in the POC below.
This issue demonstrates that a malicious submitter can bypass the challenge period and finalize invalid LPPs. Since this data is assumed to be correct and is used in the MIPS.sol, this attack allows a malicious submitter to successfully challenge valid claims and forge invalid claims that cannot be challenged. In summary, the attack has no preconditions, can be executed by anyone, and completely breaks the fault dispute game logic. Thats why I believe the severity is HIGH.
Consider checking that the proposal was finalized in the squeezeLPP function:
Invalid Validation
ajsutton (Optimism) confirmed
