On June 10 and June 16, 2022, Aurora Labs received two bug reports with critical severity on its Immunefi's bug bounty program.
For their valuable contribution to keeping Aurora a safe place for its users, both hackers were rewarded the maximum amount of the bug bounty program, which is $1M in Aurora tokens, unlocking over a continuously vesting period of 1 year.
The two reported bugs were pretty different and require both their explanations, so let’s proceed to a split analysis:
Part 1: Withdraw from EthCustodian without burn on Aurora bug summary
Description of the vulnerability
An attacker could withdraw assets from the Rainbow Bridge lockers on Ethereum without burning the corresponding assets on the NEAR/Aurora side of the bridge. This theft of funds could prevent legitimate user withdrawals in the future (if there were not enough funds left in the locker).
The vulnerability was caused by the fact that the bridge uses return values from the Engine to indicate burn events on Aurora, which then indicate to the locker to release funds on the Ethereum side. However, since the Engine contract contains the EVM, a Turing-complete VM, it means a clever attacker can cause the Engine to create output that looks like a burn event on Aurora without any such event occurring. The spoofed output is then used to withdraw funds from the locker on Ethereum.
As a short-term solution we implemented a check in the engine which forbids output that could be parsed as a bridge withdrawal event (except from the actual withdrawal function of course). This closes the vulnerability, but is a little hacky. The long term solution (which the bridge team is working on) is to have the bridge operate on NEAR proofs of state (i.e. actual token balances) instead of proofs of output from transactions.
As a side note, the reason using output from transactions as proof of events in the bridge is not secure is because of the Turing-complete EVM being co-located with this bridge maintenance logic. This bug report talked about ETH being at risk, and this could be entirely avoided if the events were emitted from a separate contract from the Engine (this split of the NEP-141 ETH logic from the rest of the Engine has been discussed on Aurora’s forum for some time now).
That change would have prevented the reported bug, but the same principle applies to stealing bridged ERC-20 tokens as well. Therefore, similarly, the bridge events should have been coming from the separate accounts containing the NEP-141 logic (e.g. dac17f958d2ee523a2206206994597c13d831ec7.factory.bridge.near) instead of the Engine itself. The key point is that it is always dangerous to co-locate sensitive business logic with a Turing-complete VM accepting arbitrary user input. This should be kept in mind going forward.
Part 2: Ft_on_transfer bug summary
Description of the vulnerability
The flow for bridging NEP-141 tokens from NEAR into Aurora as ERC-20 tokens could be misused by an attacker to steal ETH from any address on Aurora. Note: this same flow is used to bridge ERC-20 tokens from Ethereum to Aurora since that is done by first bridging the Ethereum ERC-20 to NEAR as a NEP-141 and then the NEAR token is bridged to Aurora. The attacker must target addresses individually and each instance of the attack could only steal at most 18.4 ETH (even if the balance of the target address is higher).
The problematic part of the NEP-141 bridging flow is the option to charge a fee (denominated in ETH) to the recipient. The recipient is never required to approve this fee, and due to the permissionless nature of the bridge, anyone can bridge over any token. Therefore, the attacker can create a worthless NEP-141 token on NEAR, bridge it to Aurora, then start sending it to target addresses on Aurora while charging a fee. Since the NEP-141 token is worthless and transactions on NEAR are cheap, this means the attacker can take ETH from Aurora addresses essentially for free.
Root cause of the problem
The root cause is really a design flaw. The design never should have included a fee which the recipient does not explicitly agree to. The purpose of this fee was to allow the bridge front-end to cover the NEAR cost of bridging ERC-20 tokens from Ethereum to Aurora (the typical user does not have a NEAR account, only an Aurora address, and this bridging operation is fundamentally happening on NEAR as opposed to the Aurora EVM). However, this fee was never enabled because the operation of the bridge is subsidized through the Aurora validator on NEAR.
Since the fee was never used legitimately by the bridge front-end, we simply removed the logic which sets a non-zero fee. To avoid similar problems in the future, we will make sure the user who’s paying a fee will be required to explicitly agree to it, by signing a transaction for example.
Focused on Aurora's smart contracts and web application, Aurora’s bug bounty program welcomes all white hat hackers wanting to contribute to global web3 security and get rewarded for it.
This program targets the prevention of:
- Loss of assets held in their Rainbow Bridge
- Loss of any user funds, whether at-rest or in-motion
- Permanent freezing of funds
- Loss of governance funds
- Inability to call smart contract
- Thefts and freezing of unclaimed yield of any amount
This is not the first time the program has proven its utility, as the first critical bug report was received on April 26, 2022. We also published a detailed article about this issue back then, which you can read here.
Want to know more about the bug bounty program itself? Check it out on Immunefi.