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

Borrower Can Permanently Invalidate Push Provider Credentials Through Block/Unblock Actions #238

Open
c4-bot-9 opened this issue Sep 18, 2024 · 0 comments
Labels
2 (Med Risk) Assets not at direct risk, but function/availability of the protocol could be impacted or leak value bug Something isn't working 🤖_104_group AI based duplicate group recommendation sufficient quality report This report is of sufficient quality

Comments

@c4-bot-9
Copy link
Contributor

Lines of code

https://github.com/code-423n4/2024-08-wildcat/blob/fe746cc0fbedc4447a981a50e6ba4c95f98b9fe1/src/access/AccessControlHooks.sol#L447-L449

Vulnerability details

The current implementation allows the borrower to permanently invalidate credentials provided by push providers through a sequence of blocking and unblocking actions. This vulnerability undermines the access control system and gives the borrower unintended power over lender credentials.

Proof of Concept

A push provider grants a credential to a lender:

function _grantRole(
    RoleProvider callingProvider,
    address account,
    uint32 roleGrantedTimestamp
) internal {
    // ...
    _setCredentialAndEmitAccessGranted(status, callingProvider, account, roleGrantedTimestamp);
}

The borrower can then invalidate this credential:

function blockFromDeposits(address account) external onlyBorrower {
    LenderStatus memory status = _lenderStatus[account];
    if (status.hasCredential()) {
        status.unsetCredential();
        emit AccountAccessRevoked(account);
    }
    status.isBlockedFromDeposits = true;
    _lenderStatus[account] = status;
    emit AccountBlockedFromDeposits(account);
}

The borrower can then unblock the lender, but the credential remains invalidated:

function unblockFromDeposits(address account) external onlyBorrower {
    LenderStatus memory status = _lenderStatus[account];
    status.isBlockedFromDeposits = false;
    _lenderStatus[account] = status;
    emit AccountUnblockedFromDeposits(account);
}

However, push provider credentials can't be refreshed.

Exploit scenario:

  1. Alice receives a credential from a push provider.
  2. The borrower calls blockFromDeposits(alice), clearing Alice's credential.
  3. The borrower calls unblockFromDeposits(alice), unblocking Alice but not restoring her credential.
  4. Alice's push provider credential is now permanently invalidated.
  5. Alice can't participate in the market until the push provider manually grants a new credential again.

This allows the borrower to arbitrarily and permanently revoke access granted by push providers, which is likely not the intended behavior of the system.

Recommended Mitigation Steps

Separate blocking from credential management.

Assessed type

Access Control

@c4-bot-9 c4-bot-9 added 2 (Med Risk) Assets not at direct risk, but function/availability of the protocol could be impacted or leak value bug Something isn't working labels Sep 18, 2024
c4-bot-9 added a commit that referenced this issue Sep 18, 2024
@c4-bot-12 c4-bot-12 added the 🤖_104_group AI based duplicate group recommendation label Sep 18, 2024
howlbot-integration bot added a commit that referenced this issue Sep 20, 2024
@howlbot-integration howlbot-integration bot added the sufficient quality report This report is of sufficient quality label Sep 20, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
2 (Med Risk) Assets not at direct risk, but function/availability of the protocol could be impacted or leak value bug Something isn't working 🤖_104_group AI based duplicate group recommendation sufficient quality report This report is of sufficient quality
Projects
None yet
Development

No branches or pull requests

2 participants