Beginner FriendlySolidity
100 EXP
View results
Submission Details
Severity: high
Valid

Unauthorized Withdrawal Vulnerability in InheritanceManager Contract

Summary

The InheritanceManager contract has a vulnerability in its inheritance and withdrawal mechanisms. Specifically, unauthorized users can perform a withdrawal action even though the isInherited flag should prevent them from doing so. The issue occurs due to improper enforcement of access control and lack of correct validation around the isInherited flag.

Vulnerability Details

The withdrawInheritedFunds function is intended to allow only beneficiaries, after the inheritance flag (isInherited) has been set to true, to withdraw funds. However, it has been observed that an unauthorized user (user2) was able to withdraw funds despite not having inherited the contract. The vulnerability lies in the improper handling of the isInherited flag, which allows unauthorized users to bypass the intended security checks.

Impact

  1. Unauthorized Withdrawals:

    • Attackers can exploit this vulnerability to withdraw funds from the contract, potentially siphoning assets meant only for the rightful beneficiaries.

  2. Loss of Control:

    • By bypassing access control restrictions, an attacker could withdraw all funds, potentially destabilizing the contract or causing financial losses to the intended recipients.

  3. Inadequate Security Enforcement:

    • The failure to correctly enforce the isInherited flag means that the contract cannot guarantee that only authorized users can access the funds, undermining the contract's core functionality.

  4. Potential Contract Exploitation:

    • If other functions or states depend on the inheritance condition (such as claiming inheritance), this vulnerability could allow unauthorized users to claim ownership or perform actions they shouldn't be able to, leading to further exploitation.

Tools Used

Foundry

PoC

function testUnauthorizedWithdrawalWhileFlagTrue() public {
// 1. Set up the beneficiaries
vm.startPrank(owner);
im.addBeneficiery(user1);
im.addBeneficiery(user2);
vm.stopPrank();
// 2. Simulate inactivity and inheritance
vm.warp(block.timestamp + 90 days); // Simulate 90 days passing
// 3. Make a call to inherit() with user1
vm.startPrank(user1);
im.inherit(); // User1 becomes the owner
vm.stopPrank();
// 4. Ensure that the isInherited flag is true after inheritance
assertEq(im.getIsInherited(), true, "isInherited flag should be true after inheritance");
// 5. Try to perform a withdraw as an unauthorized user (user2)
console.log("Attempting unauthorized withdrawal by user2...");
vm.startPrank(user2);
// Expecting the unauthorized withdrawal to succeed as the check is removed
vm.expectRevert();
im.withdrawInheritedFunds(address(0)); // Attempt withdrawal
console.log("Unauthorized withdrawal by user2 reverted as expected.");
vm.stopPrank();
}

Recommendations

  • Fix Inheritance Checks:

    The withdrawInheritedFunds function should enforce a strict check to ensure that only users who have inherited the contract can withdraw funds. This check must be present and functional at all times. A conditional check like if (!isInherited) should revert unauthorized actions.

  • Ensure Proper isInherited Flag Management:

    The isInherited flag should be properly toggled and validated within the inheritance logic. Any attempt to withdraw funds should only succeed if this flag is set to true and the caller is authorized (i.e., a beneficiary).

  • Access Control Enforcement:

    Access to critical functions like inherit and withdrawInheritedFunds should be tightly controlled to ensure that only the rightful owner (or those who have inherited the contract) can execute these functions. Non-beneficiaries should not be able to execute any of these functions.

Updates

Lead Judging Commences

0xtimefliez Lead Judge 4 months ago
Submission Judgement Published
Validated
Assigned finding tags:

Inherit depends on msg.sender so anyone can claim the contract

Support

FAQs

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