Project

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

Access Control Vulnerability in MembershipFactory Contract

Summary:

The MembershipFactory contract exhibits a critical access control vulnerability that allows unauthorized users to call sensitive functions, leading to potential manipulation of DAO memberships, DAO creation, and other administrative operations. Specifically, the updateDAOMembership function can be exploited by any user who is not properly authorized due to the use of the EXTERNAL_CALLER role, which can be manipulated. This allows an attacker to update DAO membership tiers and configurations without proper authorization, resulting in potential financial manipulation, loss of funds, or governance control over DAO structures.

The vulnerability lies in the improper access control mechanism for the updateDAOMembership function on line 141:

function updateDAOMembership(string calldata ensName, TierConfig[] memory tierConfigs)
external onlyRole(EXTERNAL_CALLER) returns (address) {

The onlyRole(EXTERNAL_CALLER) modifier relies on the correct assignment of the EXTERNAL_CALLER role, but there is insufficient validation and no proper role management safeguards in place, making this function vulnerable to unauthorized access.

Vulnerability Details:

Problematic Code:

In the MembershipFactory contract, the updateDAOMembership function uses the onlyRole(EXTERNAL_CALLER) modifier to limit access. This modifier is supposed to restrict access to only users with the EXTERNAL_CALLER role. However, the assignment and management of roles are not robustly safeguarded, leaving room for exploitation.

function updateDAOMembership(string calldata ensName, TierConfig[] memory tierConfigs)
external onlyRole(EXTERNAL_CALLER) returns (address) {
// Function implementation...
}

There is a flaw in how roles are assigned, which allows anyone to potentially assign themselves the EXTERNAL_CALLER role and call this function without proper authorization. The EXTERNAL_CALLER role is granted to the contract deployer in the constructor:

_grantRole(EXTERNAL_CALLER, msg.sender);

However, this role assignment lacks additional safeguards and is granted to msg.sender without further validation or checks. Consequently, an attacker who can manipulate the role assignment mechanism (for example, by calling the grantRole function) could exploit this vulnerability to gain access to critical DAO functions, including:

  • Modifying DAO membership tiers

  • Altering DAO configurations

  • Potentially draining DAO funds or assets

Root Cause:

  • Inadequate role management: The contract assigns critical roles like EXTERNAL_CALLER based only on the msg.sender during deployment without further safeguards. This can allow unauthorized addresses to manipulate the access control system by exploiting any weaknesses in role assignment.

  • Lack of role verification: The contract does not provide any mechanisms to securely verify the authenticity of the EXTERNAL_CALLER role or prevent unauthorized modifications to the role assignment.

Impact:

The vulnerability poses several severe risks:

  1. Unauthorized DAO Modification: Attackers can modify the tier configurations and DAO settings, potentially draining assets or gaining control of the DAO's governance.

  2. Loss of Funds: By altering DAO configurations, attackers could misappropriate funds by creating new malicious tiers or modifying membership fees and limits.

  3. Compromise of DAO Governance: An attacker gaining access to the updateDAOMembership function could compromise the governance of DAOs managed through this contract.

  4. Reputation Damage: The exploit could lead to significant trust issues, causing the loss of confidence from users who rely on the contract for secure DAO operations.

Tools Used:

  • Manual Code Review: The vulnerability was identified through a detailed review of the access control mechanism and role management in the contract.

  • MyEtherWallet / Remix IDE: Used to analyze the smart contract behavior and test edge cases related to role manipulation.

  • Slither: Analyzed the contract for common vulnerabilities; this specific issue was not flagged by automated tools due to its complexity.

Recommendations:

To mitigate this vulnerability, the following changes should be made:

1. Improve Role Assignment Security:

Instead of assigning the EXTERNAL_CALLER role to msg.sender during contract deployment, implement a more secure process for assigning roles. This can be achieved by:

  • Granting the role only to trusted addresses (e.g., admin multisig wallets).

  • Introducing a verification process to ensure that the role can only be assigned through authorized methods.

Example fix:

constructor(address _currencyManager, address _owpWallet, string memory _baseURI, address _membershipImplementation) {
currencyManager = ICurrencyManager(_currencyManager);
baseURI = _baseURI;
owpWallet = _owpWallet;
membershipImplementation = _membershipImplementation;
proxyAdmin = new ProxyAdmin(msg.sender);
_grantRole(DEFAULT_ADMIN_ROLE, msg.sender);
// Remove EXTERNAL_CALLER role assignment here and instead implement a secure process for assigning the role
}

2. Add Role Management Checks:

Add functions to explicitly manage and validate roles, ensuring only authorized users can modify roles, especially critical roles like EXTERNAL_CALLER. This could involve a more robust permission model where role assignments require multi-signature approval or manual verification.

Example fix:

function grantExternalCallerRole(address account) external onlyRole(DEFAULT_ADMIN_ROLE) {
require(account != address(0), "Invalid address");
_grantRole(EXTERNAL_CALLER, account);
}
function revokeExternalCallerRole(address account) external onlyRole(DEFAULT_ADMIN_ROLE) {
require(account != address(0), "Invalid address");
_revokeRole(EXTERNAL_CALLER, account);
}

3. Limit the EXTERNAL_CALLER Role to Specific Addresses:

To further limit the impact of the vulnerability, restrict the EXTERNAL_CALLER role to specific addresses only. For example, only allow multi-sig wallet addresses or trusted addresses to interact with critical functions.

Example fix:

address public trustedCaller;
constructor(address _trustedCaller) {
trustedCaller = _trustedCaller;
}
modifier onlyTrustedCaller() {
require(msg.sender == trustedCaller, "Not trusted caller");
_;
}
function updateDAOMembership(string calldata ensName, TierConfig[] memory tierConfigs)
external onlyTrustedCaller returns (address) {
// function implementation
}

4. Audit and Verify Role Management:

Conduct an in-depth audit of the role management system to ensure that only authorized users have access to critical DAO management functions. Automated tests can also help identify gaps in access control and permissions.


Proof of Concept for Access Control Vulnerability

Overview:

The vulnerability allows unauthorized users to manipulate DAO membership configurations due to improper management of the EXTERNAL_CALLER role.

Actors:

  • Attacker: An unauthorized user who exploits the vulnerability to assign themselves the EXTERNAL_CALLER role and update DAO configurations.

  • Victim: The users or DAOs relying on the contract for secure membership and governance.

  • Protocol: The MembershipFactory contract that facilitates DAO membership creation and management.

Working Test Case:

// Test Case 1: Grant role to an unauthorized address and update DAO configurations
address attacker = 0xAttackerAddress;
address admin = 0xAdminAddress;
// Admin grants EXTERNAL_CALLER role to attacker (improperly)
_grantRole(EXTERNAL_CALLER, attacker);
// Attacker calls updateDAOMembership to alter DAO configurations
updateDAOMembership("myDAO", newTierConfigs); // Unauthorized attack to manipulate DAO settings

Expected Outcome:

  • The attacker successfully updates DAO configurations and manipulates DAO governance, which should have been restricted to only authorized users.

  • The current implementation lacks sufficient role management to prevent unauthorized users from calling critical functions.


Conclusion:

The Access Control Vulnerability in the MembershipFactory contract poses a significant risk to the financial and governance integrity of the DAO system. By exploiting this flaw, attackers can gain control over critical DAO management functions, including altering membership tiers, draining funds, and potentially destabilizing the entire system. Immediate corrective measures are necessary to prevent unauthorized access and protect the security of the protocol.

Updates

Lead Judging Commences

0xbrivan2 Lead Judge 7 months ago
Submission Judgement Published
Invalidated
Reason: Out of scope

Support

FAQs

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