Open hats-bug-reporter[bot] opened 4 days ago
@0xmahdirostami this scenario is not possible, becuase the Safe only can exist in onw org, not in both if you check the require in addSafe
, registerOrg
or createRootSafe
, if the safe is Already register and then, tx revert!!
@alfredolopez80
it's not about safe, it's about user
.
function setRole(
DataTypes.Role role,
address user,
uint256 safeId,
bool enabled
)
Any root of any org could set a role or revoke a role for any user.
In my POC, the root of first organization sets SAFE_LEAD_MODIFY_OWNERS_ONLY
role for safeA1Id
for userEOALead
(uint256 rootId, uint256 safeA1Id) =
palmeraSafeBuilder.setupRootOrgAndOneSafe(orgName, safeA1Name);
address rootAddr = palmeraModule.getSafeAddress(rootId);
address userEOALead = address(0x123);
// Root of the first organization assigns `SAFE_LEAD_MODIFY_OWNERS_ONLY` role to userEOALead.
vm.startPrank(rootAddr);
palmeraModule.setRole(
DataTypes.Role.SAFE_LEAD_MODIFY_OWNERS_ONLY,
userEOALead,
safeA1Id,
true
);
after that, the malicious user could create a new org, and set any role or revoke any role for this user.
(uint256 rootId2, uint256 safeA1Id2) =
palmeraSafeBuilder.setupRootOrgAndOneSafe(org2Name, safeA2Name);
address rootAddr2 = palmeraModule.getSafeAddress(rootId2);
vm.startPrank(rootAddr2);
// Root of the second organization revokes `SAFE_LEAD_MODIFY_OWNERS_ONLY` and assigns `SAFE_LEAD_EXEC_ON_BEHALF_ONLY` to userEOALead.
palmeraModule.setRole(
DataTypes.Role.SAFE_LEAD_MODIFY_OWNERS_ONLY,
userEOALead,
safeA1Id2,
false
);
palmeraModule.setRole(
DataTypes.Role.SAFE_LEAD_EXEC_ON_BEHALF_ONLY,
userEOALead,
safeA1Id2,
true
);
assertEq(
palmeraRolesContract.doesUserHaveRole(
userEOALead, uint8(DataTypes.Role.SAFE_LEAD_MODIFY_OWNERS_ONLY)
),
false
);
assertEq(
palmeraRolesContract.doesUserHaveRole(
userEOALead, uint8(DataTypes.Role.SAFE_LEAD_EXEC_ON_BEHALF_ONLY)
),
true
);
}
As you see rootAddr2
revokes SAFE_LEAD_MODIFY_OWNERS_ONLY
role for new safe safeA1Id2
, but the same user (userEOALead), so now this doesn't have that role.
it's not important in the second function what is safeId
.
root could assign any role to any user
For example, there is an Org called uniOrg
that the root of it, assigns SAFE_LEAD_MODIFY_OWNERS_ONLY
for safeID1 for user A.
Any user could create a new Org and revoke this role from user A Or assign new role for this user,
is issue valid @0xmahdirostami
Github username: @0xmahdirostami Twitter username: 0xmahdirostami Submission hash (on-chain): 0xcac9230f2dc40110a888f845f4e7337b88cbd193f8110efb6f7c010d9e074bd1 Severity: high
Description: Description: In the
setRole
function:The
safeId
parameter is intended to specify the safe on which the user will have permissions. However, the current implementation assigns roles to the user without considering thesafeId
. This means roles are assigned to the user generally, not just for that specificsafeId
:This allows any root to enable or disable any role for any user without restriction, so the root of any organization can enable or disable roles for any user.
Scenario:
uniOrg
. This organization assigns user A to role A. A malicious attacker creates an organization calledXOrg
with one safe in his organization. This malicious root can callsetRole
with hissafeId
and user A's address to disable role A for user A or assign any other role to user A.SAFE_LEAD_MODIFY_OWNERS_ONLY
role in an organization and leads safe ID 2, they could create a new organization with another safe wallet and assignSAFE_LEAD_EXEC_ON_BEHALF_ONLY
to their address.Impact:
Proof of Concept (PoC): Add the following test to
PalmeraRolesTest.t.sol
:As shown above, root2 can change user roles arbitrarily, demonstrating the vulnerability.
Mitigation: Ensure that when setting a role, the
safeId
anduser
are considered together. The role assigned to a user must be specific to thatsafeId
.