Beginner FriendlyDeFiFoundry
100 EXP
View results
Submission Details
Severity: medium
Valid

Flaw in `Laundrette::quiTheGang` function: any member of the gang can kick another member.

Summary

Flaw in Laundrette::quiTheGang function: any member of the gang can kick another member.

Vulnerability Details

Unauthorized Role Revocation by Any Gang Member:

Any member with the gangmember role could potentially revoke the role of any other member. This could lead to malicious activities where one member revokes the roles of other members, causing disruptions within the system.

  1. Unauthorized Access:
    If a gang member can revoke the role of any other member, it undermines the principle of least privilege. Members could exercise power beyond their intended scope, leading to potential abuse.

  2. Operational Disruption:
    Revoking roles disrupts the normal operations of the contract. Members who have their roles revoked might be unable to perform essential functions, leading to operational inefficiencies or failure of certain functionalities.

  3. Potential for Internal Conflict:
    If gang members can revoke each other's roles without restrictions, it could lead to internal conflicts and mistrust among members. This could erode the cohesion and cooperation within the gang.

Impact

Failing to add the require statement to the quitTheGang function can lead to unauthorized role revocations, operational disruptions, and governance challenges.

Example Scenarios:

  • Scenario 1: Malicious Member:

    • A malicious gang member, Alice, decides to revoke the roles of all other members. Without the require statement, Alice can call quitTheGang for each member, effectively removing them from the gang and gaining control.

  • Scenario 2: Compromised Account:

    • Bob, a gang member, has his account compromised. The attacker uses Bob's credentials to revoke the roles of other gang members, causing chaos and potentially taking over the gang’s operations.

PoC

Add BaseTest::addToGang and LaundretteTest::testKickGangMember

Unit test

function addToGang(address account) internal {
vm.prank(godFather);
laundrette.addToTheGang(account);
}
function testKickGangMember() public {
joinGang(gangMemberOne);
assertEq(kernel.hasRole(gangMemberOne, Role.wrap("gangmember")), true);
addToGang(gangMemberTwo);
assertEq(kernel.hasRole(gangMemberTwo, Role.wrap("gangmember")), true);
vm.startPrank(gangMemberTwo);
laundrette.quitTheGang(gangMemberOne);
assertEq(kernel.hasRole(gangMemberOne, Role.wrap("gangmember")), false);
vm.stopPrank();
}

Traces output

vesper3023@LAPTOP-7INTR2BC:~/First_Flight/2024-05-mafia-take-down$ forge test --match-test testKickGangMember
[⠊] Compiling...
[⠃] Compiling 7 files with 0.8.24
[⠊] Solc 0.8.24 finished in 2.78s
Compiler run successful!
Ran 1 test for test/Laundrette.t.sol:LaundretteTest
[PASS] testKickGangMember() (gas: 140904)
Suite result: ok. 1 passed; 0 failed; 0 skipped; finished in 5.29ms (1.02ms CPU time)
Ran 1 test suite in 13.00ms (5.29ms CPU time): 1 tests passed, 0 failed, 0 skipped (1 total tests)

Test pass, this means that any member can kick any address.

Tools Used

Manual review.

Unit test (Foundry).

Recommendations

By adding the require statement in Laundrette::quitTheGang to ensure that only the account itself or the godFather can revoke the role, you significantly reduce these vulnerabilities and improve the overall security and robustness of the contract.

  • require(account == msg.sender || kernel.executor() == msg.sender, "Caller must be the account itself or the GodFather" );

Mitigation Approach

  • Add require function in The Laundrette::quitTheGang to validate inputs and conditions before execution.

function quitTheGang(address account) external onlyRole("gangmember")
{
+ require(account == msg.sender || kernel.executor() == msg.sender, "Caller must be the account itself or the GodFather");
kernel.revokeRole(Role.wrap("gangmember"), account);
}

Error handling: Assert, Require, Revert and Exceptions

Validation

Methodology, we are using the same unit test showed in impact section.

Return of forge test --match-test testKickGangMember unit test

vesper3023@LAPTOP-7INTR2BC:~/First_Flight/2024-05-mafia-take-down$ forge test --match-test testKickGangMember
[⠊] Compiling...
No files changed, compilation skipped
Ran 1 test for test/Laundrette.t.sol:LaundretteTest
[FAIL. Reason: revert: Caller must be the account itself or the GodFather] testKickGangMember() (gas: 156431)
Suite result: FAILED. 0 passed; 1 failed; 0 skipped; finished in 5.54ms (1.04ms CPU time)
Ran 1 test suite in 15.29ms (5.54ms CPU time): 0 tests passed, 1 failed, 0 skipped (1 total tests)
Failing tests:
Encountered 1 failing test in test/Laundrette.t.sol:LaundretteTest
[FAIL. Reason: revert: Caller must be the account itself or the GodFather] testKickGangMember() (gas: 156431)
Encountered a total of 1 failing tests, 0 tests succeeded

Laundrette::quitTheGang revert as expected by applying unauthorized access control.

Updates

Lead Judging Commences

n0kto Lead Judge about 1 year ago
Submission Judgement Published
Validated
Assigned finding tags:

Gang members ban other members

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.