Skip to content

Latest commit

 

History

History
126 lines (91 loc) · 8.36 KB

031.md

File metadata and controls

126 lines (91 loc) · 8.36 KB

Glamorous Plum Baboon

High

Malicious Actor Can Liquidate Excess Collateral and Impact Protocol Stability

Summary

The lack of proper access control in the LiquidationLogic:executeLiquidationCall function will cause an unauthorized liquidation for protocol users as malicious actors will call the function with malicious parameters to liquidate collateral without permission.

Root Cause

In LiquidationLogic.sol:executeLiquidationCall function lacks an access control mechanism, which will cause a potential security vulnerability. Specifically, the function does not check whether the caller has the necessary permissions, allowing any address to invoke it and potentially execute malicious liquidation actions. This oversight could lead to unauthorized users performing liquidations, impacting the protocol's security.

https://github.com/sherlock-audit/2025-01-aave-v3-3/blob/main/aave-v3-origin/src/contracts/protocol/libraries/logic/LiquidationLogic.sol#L200-L434

Internal Pre-conditions

For the Lack of Access Control vulnerability in the executeLiquidationCall function, the following internal pre-conditions would need to be met in order for the attack path or vulnerability to be exploited:

  1. Any external actor needs to call executeLiquidationCall without proper authorization to set params.user to be any user.
  2. Any external actor needs to call executeLiquidationCall to set params.collateralAsset and params.debtAsset to be valid collateral and debt assets within the system, without verifying if they have the permission to execute the liquidation.
  3. Any external actor needs to call executeLiquidationCall to set params.debtToCover to be at most the amount that is actually owed (or even beyond the user's debt).
  4. Any external actor needs to call executeLiquidationCall to bypass access control and modify liquidation parameters without authentication.

External Pre-conditions

For the Lack of Access Control vulnerability in the executeLiquidationCall function, the following external pre-conditions would need to be met in order for the attack path or vulnerability to be exploited:

  1. Any external user or malicious actor needs to have the ability to interact with the contract by calling the executeLiquidationCall function, without any restrictions such as authentication or authorization checks.
  2. External entities (such as a malicious user or bot) need to be able to provide parameters like params.user, params.collateralAsset, and params.debtAsset to execute a liquidation on a user without verifying their authority or permission to do so.
  3. External interactions such as external price feeds or oracle updates may feed in manipulated or false data, enabling an attacker to influence liquidation calculations if no validation or access control is present on who can call the liquidation function.
  4. A malicious actor needs to exploit the ability to call the function with manipulated parameters, potentially triggering a liquidation event on an innocent user or themselves by bypassing proper authorization checks.

Attack Path

The attack path for the Lack of Access Control vulnerability in the executeLiquidationCall function:

  1. Malicious User calls the executeLiquidationCall function on the smart contract, without any authentication or access control mechanisms restricting the caller.
  2. The Malicious User provides manipulated parameters in the function call, such as their own address as params.user, and chooses arbitrary assets for params.collateralAsset and params.debtAsset, bypassing any validation checks that would normally prevent unauthorized access.
  3. The smart contract executes the function with the parameters provided by the malicious actor, proceeding with the liquidation process, which includes calling internal functions like _calculateAvailableCollateralToLiquidate, _burnDebtTokens, and transferring collateral and debt assets.
  4. The malicious actor successfully triggers a liquidation of a user’s collateral, potentially liquidating assets they don’t own or performing an undesired liquidation event.
  5. The smart contract does not perform proper validation to ensure the caller is authorized, so the attack goes unchecked and could lead to significant financial loss for the victim or the protocol.

In this attack, the attacker exploits the lack of access control, bypassing any authorization checks, and is able to cause liquidations that should only be allowed for authorized roles.

Impact

The affected party (the protocol) suffers an approximate loss from the mishandling of collateral and debt due to unauthorized liquidation, leading to potential financial risks, manipulation of liquidation events, or loss of funds. The attacker gains the opportunity to profit from the unauthorized liquidation process

PoC

// Assuming the LiquidationLogic contract and related contracts are already deployed

// Exploiting the executeLiquidationCall function without permission contract MaliciousActor { address liquidationLogicAddress; // Address of the LiquidationLogic contract address targetUser; // The user whose assets are to be liquidated address collateralAsset; // Asset being used as collateral address debtAsset; // Debt the user owes uint256 debtToCover; // Amount of debt to liquidate bool receiveAToken; // Whether to receive aTokens or burn collateral

// Assume LiquidationCallParams structure is properly constructed
struct ExecuteLiquidationCallParams {
    address user;
    address collateralAsset;
    address debtAsset;
    uint256 debtToCover;
    bool receiveAToken;
    uint256 reservesCount;
    uint8 userEModeCategory;
    address priceOracle;
    address priceOracleSentinel;
}

// Function to exploit the vulnerability
function exploitLiquidation() external {
    // Constructing the malicious parameters
    ExecuteLiquidationCallParams memory params = ExecuteLiquidationCallParams({
        user: targetUser, // The victim's address
        collateralAsset: collateralAsset, // The asset to be liquidated
        debtAsset: debtAsset, // The debt asset to be liquidated
        debtToCover: debtToCover, // The debt amount to be liquidated
        receiveAToken: receiveAToken, // Whether to receive aTokens
        reservesCount: 2, // Number of reserves, assuming 2 for this example
        userEModeCategory: 0, // User's EMode category, set to 0 (default)
        priceOracle: address(0), // Oracle for price, assuming a mock address
        priceOracleSentinel: address(0) // Sentinel for price oracle checks
    });

    // Calling the executeLiquidationCall function on the LiquidationLogic contract
    (bool success, ) = liquidationLogicAddress.call(
        abi.encodeWithSignature("executeLiquidationCall(address,address,address,address,uint256,bool,uint256,uint8,address,address)",
        params.user,
        params.collateralAsset,
        params.debtAsset,
        params.debtToCover,
        params.receiveAToken,
        params.reservesCount,
        params.userEModeCategory,
        params.priceOracle,
        params.priceOracleSentinel
    ));

    // If the function executes, the malicious actor successfully triggered a liquidation
    require(success, "Liquidation failed");
}

}

Results of the Attack: Target User: The collateral assets of the target user would be liquidated, resulting in a potential loss of their funds.

Attacker: If the attacker successfully triggers the liquidation, they may profit from the collateral liquidation (if allowed by the contract’s logic). Additionally, the attacker can manipulate liquidation parameters to their advantage.

Mitigation

Use OpenZeppelin’s AccessControl for Role-based Access If you require multiple roles to access different functions (e.g., admin, manager), AccessControl allows you to assign specific roles to addresses and restrict function execution accordingly

2, Use OpenZeppelin’s AccessControl or Ownable OpenZeppelin’s smart contract libraries are well-established and widely used. The AccessControl contract is a robust solution for managing roles, while the Ownable contract is a simpler solution for managing an owner of the contract.