Platform: Code4rena
Start Date: 18/10/2023
Pot Size: $36,500 USDC
Total HM: 17
Participants: 77
Period: 7 days
Judge: MiloTruck
Total Solo HM: 5
Id: 297
League: ETH
Rank: 56/77
Findings: 1
Award: $37.14
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: MrPotatoMagic
Also found by: Bughunter101, COSMIC-BEE-REACH, HChang26, Stormreckson, T1MOH, Tendency, hals, josephdara, klau5, merlin, tnquanghuy0512, twcctop
37.1417 USDC - $37.14
https://github.com/open-dollar/od-contracts/blob/f4f0246bb26277249c1d5afe6201d4d9096e52e6/src/contracts/proxies/ODSafeManager.sol#L105 https://github.com/open-dollar/od-contracts/blob/f4f0246bb26277249c1d5afe6201d4d9096e52e6/src/contracts/proxies/ODSafeManager.sol#L49
In the ODSafeManager
smart contract, there exists an allowSAFE
function that permits or restricts a user's ability to manage the safe. If the owner of the SAFE attempts to revoke access from a user with permission, there is a potential vulnerability where the allowed user could front-run the transaction to add another user. Subsequently, after the removal operation is executed, the initially removed user can leverage the newly added user to regain their authority.
The following test case illustrates the scenario:
Alice
grants permission for Bob
to manage the SAFE using the function: allowSAFE(1, Bob, 1)
.
Subsequently, Bob's intentions turn malicious, and Alice decides to revoke his access.
As Alice initiates a transaction to disallow Bob, he detects this and front-runs her tx by authorizing a new user with permission with the function: allowSAFE(1, Erin, 1)
.
When Alice's transaction is executed, it successfully disallows Bob using the function: allowSAFE(1, Bob, 0).
Now, Erin authorizes Bob to manage the SAFE once again with the function: allowSAFE(1, Bob, 1).
function allowSAFE( uint256 _safe, address _usr, uint256 _ok ) external safeAllowed(_safe) { address _owner = _safeData[_safe].owner; safeCan[_owner][_safe][_usr] = _ok; emit AllowSAFE(msg.sender, _safe, _usr, _ok); }
This would allow the malicious user with permission to keep executing txs on behalf of the owner of the SAFE.
Manual review
Prevent users who have permission from invoking the allowSAFE()
function on behalf of the SAFE owner:
function allowSAFE( uint256 _safe, address _usr, uint256 _ok - ) external safeAllowed(_safe) { + ) external { address _owner = _safeData[_safe].owner; + if (msg.sender != _owner) + revert HandlerNotAllowed(); safeCan[_owner][_safe][_usr] = _ok; emit AllowSAFE(msg.sender, _safe, _usr, _ok); }
Access Control
#0 - c4-pre-sort
2023-10-26T06:16:22Z
raymondfam marked the issue as sufficient quality report
#1 - c4-pre-sort
2023-10-26T06:16:44Z
raymondfam marked the issue as duplicate of #171
#2 - c4-judge
2023-11-02T08:44:20Z
MiloTruck marked the issue as satisfactory