Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AccessControlEnumerable doesn't override all internal functions #2938

Closed
hacker-DOM opened this issue Nov 3, 2021 · 1 comment · Fixed by #2946
Closed

AccessControlEnumerable doesn't override all internal functions #2938

hacker-DOM opened this issue Nov 3, 2021 · 1 comment · Fixed by #2946
Labels

Comments

@hacker-DOM
Copy link

Background

AccessControlEnumerable inherits from AccessControl. It overrides some public methods, but not all internal ones. For example not this one

function _grantRole(bytes32 role, address account) internal virtual {
if (!hasRole(role, account)) {
_roles[role].members[account] = true;
emit RoleGranted(role, account, _msgSender());
}
}

Vulnerability scenario

Alice is writing a contract C. I've provided mocks for the two OZ contracts to illustrate the scenario:

contract AccessControl {
    mapping (bytes32 => mapping (address => bool)) _roles;
    function _grantRole(bytes32 role, address account) internal {
        _roles[role][account] = true;
    }
}

contract AccessControlEnumerable is AccessControl {
    
}

contract C is AccessControlEnumerable {
    constructor() {
        _grantRole(hex"deadbeef", msg.sender);
    }
}

C.getRoleMemberCount(hex"deadbeef") will return 0.

Recommendation

Short term, override the internal methods of AccessControlEnumerable. This will ensure the above code behaves as expected.

Long term, remove the dependency of AccessControlEnumerable on AccessControl. AddressSet has methods to get enumeration and inclusion, so there is no need for such redundancy.

@Amxx
Copy link
Collaborator

Amxx commented Nov 4, 2021

Hello @hacker-DOM

Thank for raising that issue. AccessControl was implemented when AccessControl's grant and revoke functions were private and not internal. Now that they are internal, AccessControl should be refactored accordingly

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants