In the withdrawTokens
function, if the collectionL1
parameter is set to address(0)
, an ERC721Bridgeable
contract is deployed, and the resulting address is automatically whitelisted. This logic does not consider the situation when _whiteListEnabled == false
(i.e., when the whitelist mechanism is disabled), which leads to unintended tokens being whitelisted.
If _whiteListEnabled
is later changed to true to restrict token bridging, the previously whitelisted tokens will remain whitelisted, potentially enabling malicious or unintended tokens to be bridged without restriction. Additionally, adding a large number of tokens to the _collections
array could cause Out-of-gas issues due to excessive iteration during whitelist management.
The _whiteListEnabled
and white_list_enabled
variables on Ethereum
and Starknet
, respectively, indicate whether the whitelist mechanism is active.
If these variables are false, the whitelist check is bypassed, and all tokens are allowed to bridge across chains by default:
It is pretty sure that _whiteListEnabled
or white_list_enabled
should be set to be the same to apply same criteria for consistent cross-chain operations, otherwise the uni-directional cross-chain would cause tokens to be stuck.
The problem arises in the withdrawTokens
function, where if collectionL1 == address(0)
, a new ERC721Bridgeable
contract is deployed, and the resulting address is automatically added to the whitelist:
This is the same in bridge.cairo
:
This logic automatically adds the newly deployed collection to the whitelist regardless of the _whiteListEnabled
or white_list_enabled
values. As a result, even if _whiteListEnabled
is later changed back to true
, these tokens will remain in the whitelist, which is unintended.
Consider a following scenario:
The _whiteListEnabled
on Ethereum
and white_list_enabled
on Starknet
are both set to false. This allows any token to be bridged without restriction. A malicious token is bridged from Starknet to Ethereum. Since the whitelist is disabled, no checks are performed, and the token is accepted.
During the withdrawTokens
process, if collectionL1 == address(0)
, an ERC721Bridgeable
contract is deployed on Ethereum
. This new collectionL1
address is automatically whitelisted, regardless of the _whiteListEnabled
status. The malicious token’s collection is now part of the whitelist unintentionally.
Later, due to security concerns, the contract owner re-enables the whitelist mechanism by setting _whiteListEnabled = true
on Ethereum and white_list_enabled = true
on Starknet. However, since the malicious token’s collection was already added to the whitelist, it remains whitelisted even with the whitelist mechanism now enabled.
The malicious token can still be bridged back because it remains on the whitelist. This undermines the security purpose of re-enabling the whitelist.
Consider another scenario:
The _whiteListEnabled
on Ethereum
and white_list_enabled
on Starknet
are both set to false. This allows any token to be bridged without restriction.
A malicious actor bridges 1,000 different tokens from Starknet
to Ethereum
. Since the whitelist is disabled, all tokens are accepted without any checks.
During the withdrawTokens process, for each of the 1,000 tokens, if collectionL1 == address(0)
, an ERC721Bridgeable
contract is deployed on Ethereum
for each token. Each of these 1,000 new collectionL1
addresses is automatically whitelisted, regardless of the _whiteListEnabled
status.
The whitelist array _collections
now contains 1,000 new entries, which were automatically added due to the disabled whitelist mechanism. This massive addition of collections dilutes the whitelist array, making it cumbersome and inefficient to manage.
The _collections
array is iterated over in functions like _whiteListCollection
. With the sudden influx of 1,000 new entries, these iterations become costly in terms of gas. As the number of entries grows, operations that involve iterating over the whitelist could run into out-of-gas errors, causing critical functions to fail.
A brief PoC is shown below:
It is confirmed that the collection
is still whitelisted after _whiteListEnabled = true
.
Unintended Token Whitelisting: Tokens that should not be whitelisted may remain whitelisted, even after the whitelist mechanism is re-enabled, leading to potential security risks.
Out-of-Gas Issues: Excessive additions to the _collections
array could cause out-of-gas issues during whitelist management, particularly when iterating through the _collections
array in the _whiteListCollection
function.
Manual
To mitigate this issue, it is recommended to check the status of _whiteListEnabled
and white_list_enabled
before adding deployed tokens to the whitelist. When _whiteListEnabled == false
, tokens should not be automatically added to the whitelist.
Likelyhood: High, once the whitelist option is disabled, collections will grow. Impact: High, withdraw won’t be possible because of Out-Of-Gas.
Likelyhood: High, once the whitelist option is disabled, collections will grow. Impact: High, withdraw won’t be possible because of Out-Of-Gas.
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.