GivingThanks

First Flight #28
Beginner FriendlyFoundry
100 EXP
View results
Submission Details
Severity: high
Valid

M-03 Incorrect `isVerified` Function Allows Unverified Charities to Be Treated as Verified

Summary

In the CharityRegistry contract, the isVerified function incorrectly returns the status from the registeredCharities mapping instead of the verifiedCharities mapping. This flaw allows any registered charity to be considered verified without undergoing the proper verification process. As a result, unverified charities can receive donations intended for verified charities, posing a significant security risk.

Vulnerability Details

Affected Code:

function isVerified(address charity) public view returns (bool) {
return registeredCharities[charity];
}

Issue:

  • The isVerified function mistakenly checks the registeredCharities mapping instead of the verifiedCharities mapping.

  • This means that any charity that registers using registerCharity is automatically considered verified, even if it hasn't been approved by the admin via verifyCharity.

Proof of Concept:

Note: Before running the test, ensure that the constructor in the GivingThanks contract is corrected to properly initialize the registry variable. Update the constructor on line 16 as follows:

constructor(address _registry) ERC721("DonationReceipt", "DRC") {
- registry = CharityRegistry(msg.sender);
+ registry = CharityRegistry(_registry);
owner = msg.sender;
tokenCounter = 0;
}

The following test can be added to the existing test file and demonstrates the vulnerability:

function testIsVerifiedWithUnverifiedCharity() public {
address unverifiedCharity = makeAddr("unverifiedCharity");
// Register but don't verify the charity
vm.prank(unverifiedCharity);
registryContract.registerCharity(unverifiedCharity);
// Check that the charity is (incorrectly) considered verified
bool isVerified = registryContract.isVerified(unverifiedCharity);
assertTrue(isVerified);
}

Explanation:

  • An unverified charity registers itself using registerCharity.

  • When isVerified is called, it incorrectly returns true because it checks registeredCharities[unverifiedCharity], which is true.

  • This demonstrates that unverified charities are treated as verified, allowing them to receive donations without proper verification.

Impact

  • Bypass of Verification Process: Unverified or malicious charities can pose as verified entities.

  • Financial Loss: Donors may unknowingly send funds to fraudulent charities.

Tools Used

  • Manual Code Review: To identify the incorrect return value in the isVerified function.

  • Testing Framework: Used Forge (Foundry) to create and run the proof-of-concept test case.

Recommendations

  • Correct the isVerified Function:

    Update the function to check the verifiedCharities mapping instead:

    function isVerified(address charity) public view returns (bool) {
    - return registeredCharities[charity];
    + return verifiedCharities[charity];
    }

By implementing these changes, the contract will correctly enforce the verification process, ensuring that only properly verified charities can receive donations, thereby protecting donors and maintaining trust in the platform.

Updates

Lead Judging Commences

n0kto Lead Judge 10 months ago
Submission Judgement Published
Validated
Assigned finding tags:

finding-isVerified-return-registered-charities

Likelyhood: High, the function returns registered charities instead of verified ones. Impact: High, Any charities can be registered by anyone and will be declared as verified by this function bypassing verification.

Support

FAQs

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