Closed code423n4 closed 1 year ago
0xSorryNotSorry marked the issue as primary issue
deanamiel marked the issue as sponsor disputed
Doing this would only update the memory slots of the malicious proxy and would not affect the actual proxy nor implementation.
berndartmueller marked the issue as unsatisfactory: Invalid
Lines of code
https://github.com/code-423n4/2023-07-axelar/blob/main/contracts/gmp-sdk/upgradable/Upgradable.sol#L29-L33 https://github.com/code-423n4/2023-07-axelar/blob/main/contracts/gmp-sdk/upgradable/Upgradable.sol#L78-L80 https://github.com/code-423n4/2023-07-axelar/blob/main/contracts/gmp-sdk/upgradable/Proxy.sol#L40-L43
Vulnerability details
Impact
The
Upgradeable.onlyProxy
modifier is used to ensure that a function can only be called by the proxy and can not be directly called in theUpgradeable.sol
contract.The
onlyProxy
modifier implementation is as follows:Only the proxy contract can call a function guarded this modifier via a
delegatecall
. If directly called this modifier will revert the transaction.This modifier is used in the
Upgradeable.setup
function. Thesetup
function is used to setup theimplementation
contract with initial data.The problem here is that a malicious user can create his own
Proxy Contract
anddelegatecall
the implementation contract by calling itsUpgradeable.setup
function. This way he can bypass theonlyProxy
modifier since now theaddress(this) == implementationAddress
condition will be false and the transaction will execute.This issue is aggravated since there is no
initializer
modifier (from openzeppelin) in theUpgradeable.setup
function. Hence this function can be called multiple times.As a result the malicious user can use the above vulnerabilities to
delegatecall
theUpgradeable.setup
with his ownsetupParams
(after thesetup
is called via theProxy.constructor
) and change the state of the implementation contract and push it into an undesirable state.For example the
InterchainTokenService
contract inherits fromUpgradeable
contract. TheInterchainTokenService._setup
function is used to call theOperatable._setOperator
function to set theoperator_
address of theInterchainTokenService
. Hence an attacker can use the above mentioned attack path to set theoperator
to a malicious address and control theInterchainTokenService.setFlowLimit
function (controlled byonlyOperator
modifier) to set his own flow limits for token managers thus violating the contract state.Thus the users who use this compromised implementation contract will be susceptible to undesirable transactions.
Proof of Concept
https://github.com/code-423n4/2023-07-axelar/blob/main/contracts/gmp-sdk/upgradable/Upgradable.sol#L29-L33
https://github.com/code-423n4/2023-07-axelar/blob/main/contracts/gmp-sdk/upgradable/Upgradable.sol#L78-L80
https://github.com/code-423n4/2023-07-axelar/blob/main/contracts/gmp-sdk/upgradable/Proxy.sol#L40-L43
Tools Used
Manaul Review and VSCode
Recommended Mitigation Steps
Since the
Upgradeable.setup
function is used to setup theimplementation
contract with initial data (as per theNatspec
comments), it is recommended to addinitializer
modifier to thesetup
function so it can be only called once forinitialization
by the proxy contract (inside its constructor during deployment). So an attacker will not be able to call thesetup
function via a malicious proxy contract and change the state of the implementation contract later.Assessed type
Other