Closed c4-submissions closed 10 months ago
raymondfam marked the issue as low quality report
raymondfam marked the issue as primary issue
The ModulesManager::setupModules
function is automatically invoked as part of a Gnosis Safe IGnosisSafe::setup
execution flow. The SafeEnabler
is meant to be the target of delegatecall
instructions that permit a bypass of certain security checks that the default ModulesManager
enforces.
As such, Gnosis Safe deployments in the Brahma system are correctly instantiated and the SafeEnabler
does not need to expose this particular functionality.
alex-ppg marked the issue as unsatisfactory: Invalid
Lines of code
https://github.com/code-423n4/2023-10-brahma/blob/dd0b41031b199a0aa214e50758943712f9f574a0/contracts/src/core/SafeEnabler.sol#L43-L54
Vulnerability details
Impact
The Safe's
ModuleManager
implements additional functionsetupModules
, which firstly setsSENTINEL_MODULES
to themodules
. There's no such a function inSafeEnabler.sol
. This implies, that instead of adding_SENTINEL_MODULES
to themodules
, we will be addingaddress(0)
there. This may lead to some unexpected behavior, since enabled module will be marked asaddress(0)
, which implies it is not enabled.Proof of Concept
While looking at the documentation and the NatSpec, we can see, that
enableModule()
is based on theModuleManager.sol
from Safe. This is even explicitly mentioned in the NatSpace:When we look into
ModuleManager.sol
, we can spot, that it implements functionsetupModules
which is responsible for setting up the modules. According to that code-base,modules[SENTINEL_MODULES]
should point out toSENTINEL_MODULES
, which isaddress(0x1)
:modules[SENTINEL_MODULES] = SENTINEL_MODULES;
.However, there's no such a code in
SafeEnabler.sol
. This implies, that when we will runenableModule()
for the first time, thenmodules[module] = modules[_SENTINEL_MODULES]
will be assigned toaddress(0x0)
, instead of_SENTINEL_MODULES
.File: src/core/SafeEnabler.sol
Since we miss function
setupModules()
which setsmodules[SENTINEL_MODULES] = SENTINEL_MODULES
, then, we know thatmodules[SENTINEL_MODULES]
points toaddress(0)
. Thus, at line 53,modules[module]
is assigned toaddress(0)
, instead of_SENTINEL_MODULES
.That way, there won't be
_SENTINEL_MODULES
in themodules
, there will beaddress(0)
instead.More descriptive PoC:
The proper implementation is in Safe's
ModuleManager.sol
: https://github.com/safe-global/safe-contracts/blob/186a21a74b327f17fc41217a927dea7064f74604/contracts/base/ModuleManager.sol This is how the code works there:SENTINEL_MODULES
is set toaddress(0x1)
.setupModules()
which setsmodules[SENTINEL_MODULES] = SENTINEL_MODULES;
modules[SENTINEL_MODULES]
is nowaddress(0x1)
.enableModule(address X)
.modules[module] = modules[SENTINEL_MODULES];
, which implies thatmodules[X] = modules[SENTINEL_MODULES]
, somodules[X] = address(1)
modules[SENTINEL_MODULES] = module;
, which implies thatmodules[SENTINEL_MODULES] = X
As you see
modules[X] = address(1)
.The current implementation in
SafeEnabler.sol
works like this:_SENTINEL_MODULES
is set toaddress(0x1)
.setupModules()
, which implies thatmodules[_SENTINEL_MODULES] == address(0)
modules[_SENTINEL_MODULES]
is stilladdress(0x0)
.enableModule(address X)
.modules[module] = modules[_SENTINEL_MODULES];
, which implies thatmodules[X] = modules[_SENTINEL_MODULES]
, somodules[X] = address(0)
modules[_SENTINEL_MODULES] = module;
, which implies thatmodules[_SENTINEL_MODULES] = X
As you see,
modules[X] = address(0)
, which means that this module is not enabled at all.Tools Used
Manual code review
Recommended Mitigation Steps
Implement additional function
setupModules
- the same as it's done in Safe'sModuleManager.sol
Assessed type
Other