Project

One World
NFTDeFi
15,000 USDC
View results
Submission Details
Severity: high
Invalid

The vulnerability in the updateDAOMembership function is an insufficient authorization check that allows any caller with the EXTERNAL_CALLER role to modify another DAO's membership configuration by inputting someone else’s ensName.

Summary:

The updateDAOMembership function in MembershipFactory.sol contains a vulnerability due to an insufficient authorization check, allowing any caller with the EXTERNAL_CALLER role to modify another DAO’s membership configuration by inputting the ensName of a DAO they do not own.

Vulnerability Details:

The updateDAOMembership function restricts access to callers with the EXTERNAL_CALLER role but does not verify that the caller is the owner or administrator of the specified DAO. A malicious actor can:

/// @notice Updates the tier configurations for a specific DAO
/// @param ensName The ENS name of the DAO
/// @param tierConfigs The new tier configurations
/// @return The address of the updated DAO
function updateDAOMembership(string calldata ensName, TierConfig[] memory tierConfigs)
external onlyRole(EXTERNAL_CALLER) returns (address) {
address daoAddress = getENSAddress[ensName];
require(tierConfigs.length <= TIER_MAX, "Invalid tier count.");
require(tierConfigs.length > 0, "Invalid tier count.");
require(daoAddress != address(0), "DAO does not exist.");
DAOConfig storage dao = daos[daoAddress];
if(dao.daoType == DAOType.SPONSORED){
require(tierConfigs.length == TIER_MAX, "Invalid tier count.");
}
uint256 maxMembers = 0;
// Preserve minted values and adjust the length of dao.tiers
for (uint256 i = 0; i < tierConfigs.length; i++) {
if (i < dao.tiers.length) {
tierConfigs[i].minted = dao.tiers[i].minted;
}
}
// Reset and update the tiers array
delete dao.tiers;
for (uint256 i = 0; i < tierConfigs.length; i++) {
dao.tiers.push(tierConfigs[i]);
maxMembers += tierConfigs[i].amount;
}
// updating the ceiling limit acc to new data
if(maxMembers > dao.maxMembers){
dao.maxMembers = maxMembers;
}
dao.noOfTiers = tierConfigs.length;
return daoAddress;
}

Attack Path

  1. Create their own DAO to obtain the EXTERNAL_CALLER role and access the updateDAOMembership function.

  2. Input a different DAO’s ensName as the parameter, thereby gaining unauthorized access to modify that DAO's membership configuration.

This lack of ownership verification in the function allows an attacker to alter any DAO’s settings as long as they have the EXTERNAL_CALLER role.

Impact:

This vulnerability enables an attacker to make unauthorized changes to any DAO’s membership configuration. Specifically, they could:

  • Alter Membership Tiers: By manipulating tierConfigs, an attacker could change price, tier limits, membership distributions, or deplete the maximum member count (maxMembers), preventing legitimate members from joining or remaining in the DAO.

  • Modify Tier Resource Allocation: Changing the amount attribute in tierConfigs allows an attacker to reallocate membership resources, potentially impacting how operational resources are distributed within the DAO.

  • Disrupt Profit-Sharing and Governance: If the DAO’s structure is tied to profit-sharing, governance, or other benefits, an attacker could:

    • Reduce or eliminate other members’ access to profits by setting low or zero values in certain tiers.

    • Gain privileged access or benefits by configuring tiers to disproportionately favor themselves or accounts they control.

Tools Used:

Manual Code Review: Identified the vulnerability by examining the authorization checks in the updateDAOMembership function.

Recommendations:

To secure the function, verify that the caller is the owner or an authorized administrator of the specified DAO. One solution could be to add a check such as:

require(getENSAddress[ensName] == _msgSender(), "Caller is not the DAO owner");

This verification ensures that only the actual owner or authorized party of the DAO can make changes to its membership configuration, effectively preventing unauthorized access.

Updates

Lead Judging Commences

0xbrivan2 Lead Judge 10 months ago
Submission Judgement Published
Invalidated
Reason: Known issue

Support

FAQs

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