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

Lack of Access Control leads to Unauthorized ownership & Inheritance Takeover

Summary

The inherit() function in InheritanceManager.sol lacks an access control modifier, such as onlyBeneficiaryWithIsInherited, which allows **any user **to call the function. This vulnerability enables an unauthorized actor to fraudulently claim ownership of the contract leading to a complete loss of control for legitimate beneficiaries.

Vulnerability Details

No Access Control Check

  • The function should be restricted to valid beneficiaries, but currently, it is open to anyone (external visibility with no onlyBeneficiaryWithIsInherited modifier.

  • Ownership Takeover

    • If beneficiaries.length == 1, msg.sender becomes the new owner, meaning any attacker can immediately take over the contract by calling inherit().

if (beneficiaries.length == 1) {
owner = msg.sender;
_setDeadline();
}

  • Issue: The function blindly transfers ownership to msg.sender if only one beneficiary exists.

  • Problem: There is no check to verify that msg.sender is actually the last remaining beneficiary.

Attacker Steals Ownership

  1. The contract owner becomes inactive, reaching the getDeadline().

  2. **Any random external caller **(not just a beneficiary) calls inherit().

  3. If there's only one beneficiary (beneficiaries.length == 1), the attacker takes ownership.

  4. Legitimate heirs lose control, and the attacker can now transfer assets, update state, or withdraw funds.

POC

  • There is only one beneficiary (Alice).

  • The inactivity period ends.

  • Bob (an attacker) calls inherit() first, before Alice.

  • Bob becomes the new owner, locking Alice out.

  • Bob can now drain funds or set himself as the only beneficiary.

Impact

  • Impact: Anyone can call inherit() and steal ownership .

Tools Used

manual review

Recommendations

Access Control

  • Uses a modifier (onlyBeneficiaryWithIsInherited) to ensure only valid beneficiaries can call inherit().

  • If only one beneficiary remains, and that beneficiary is msg.sender, only then does it transfer ownership.

function inherit() external onlyBeneficiaryWithIsInherited {
if (block.timestamp < getDeadline()) {
revert InactivityPeriodNotLongEnough();
}
if (beneficiaries.length == 1 && msg.sender == beneficiaries[0]) {
owner = msg.sender;
_setDeadline();
Updates

Lead Judging Commences

0xtimefliez Lead Judge 6 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.