setGuard() function inside the SafeEnabler contract can be called by anyone.
Proof of Concept
The contract SafeEnabler is responsible for holding the bytecode to enable modules and guards for a Gnosis Safe. But this is a little bit changed in Brahma contracts to bypass the initialization procedure:
* bypasses Safe selfAuthorized check which disallows setting up guard during initialization
* Refer https://github.com/safe-global/safe-contracts/blob/186a21a74b327f17fc41217a927dea7064f74604/contracts/base/ModuleManager.sol#L32C5-L32C5
Now if we look at the function setGuard() we will see that there is just one check:
As we can see the function's visibility is set to be public and the only check is it should be called using delegatecall. It also lacks an initializer modifier to prevent it being called after initialization.
Anyone thus can call this function and set their addresses as the guard in a gnosis safe.
Tools Used
Manual
Recommended Mitigation Steps
Consider putting a restriction to authorized people or put an initializer modifier if you wish not to be called after initialization period
Lines of code
https://github.com/code-423n4/2023-10-brahma/blob/main/contracts/src/core/SafeEnabler.sol#L66
Vulnerability details
Impact
setGuard()
function inside theSafeEnabler
contract can be called by anyone.Proof of Concept
The contract
SafeEnabler
is responsible for holding the bytecode to enable modules and guards for a Gnosis Safe. But this is a little bit changed in Brahma contracts to bypass the initialization procedure:Now if we look at the function
setGuard()
we will see that there is just one check:As we can see the function's visibility is set to be public and the only check is it should be called using
delegatecall
. It also lacks aninitializer
modifier to prevent it being called after initialization. Anyone thus can call this function and set their addresses as the guard in a gnosis safe.Tools Used
Manual
Recommended Mitigation Steps
Consider putting a restriction to authorized people or put an
initializer
modifier if you wish not to be called after initialization periodAssessed type
Invalid Validation