Description:Description\
Describe the context and the effect of the vulnerability.
Attack Scenario\
After a safe was removed from org, the safe exercises lead role on target safe to call execTransactionOnBehalf() with any malicious data because the lead role on target still persist after safe removal.
It was observed that when role was set, user/safe was granted lead role
Github username: @lanrebayode Twitter username: lanrebayode1 Submission hash (on-chain): 0x9533a8977c3fabcfca99939a8dd8e06d1e95bdba7594e0af784ded8cf710f2d7 Severity: high
Description: Description\ Describe the context and the effect of the vulnerability.
Attack Scenario\ After a safe was removed from org, the safe exercises lead role on target safe to call
execTransactionOnBehalf()
with any malicious data because the lead role on target still persist after safe removal.It was observed that when role was set, user/safe was granted lead role
And when safe was removed, all roles granted was revoked
But the isLead() check does not confirm if the address still has the role
Since the target safe struct was not updated in the removal process, targetSafe.lead == safe_A(the caller)!
Attachments
Proof of Concept (PoC) File
safeRoot gives safe_A lead role of safe_Target by calling setRole()
safeRoot of an Org calls removeSafe() to remove a safe(safe_A) and clears all role given to safe_A.
But safe_A can still call
execTransactionOnBehalf()
and bypass all signatures check with any malicious data.Revised Code File (Optional) Include a check if the caller is a safe
Another fix will be to return false in the
isSafeLead()
if the user role has been revoked!