Missing Access Control (Perda de Controle de Acesso)

Perda de Controle de Acesso (Missing Access Control)

Ocorre quando as funções críticas dentro do contrato não estão protegidas adequadamente com restrições de acesso. Isso permite que qualquer usuário, mesmo aqueles não autorizados, possa executar essas funções, o que pode levar à manipulação dos dados do contrato, à apropriação de fundos ou à interrupção do seu funcionamento. Exemplo: Imagine um contrato inteligente que gerencia um fundo comum, onde várias pessoas podem depositar e retirar fundos. O contrato possui uma função withdrawAllFunds que permite retirar todos os fundos do contrato e transferi-los para um endereço específico. Se essa função não estiver protegida por um mecanismo de controle de acesso, qualquer usuário poderia chamar a withdrawAllFunds e especificar seu próprio endereço, retirando todos os fundos do contrato sem restrições. Isso resultaria na perda de todos os fundos depositados por outros usuários.

contract VulnerableContract {
    address public owner;
    uint public totalFunds;

    constructor() {
        owner = msg.sender;
    }

    function deposit() external payable {
        totalFunds += msg.value;
    }

    function withdrawAllFunds(address payable _to) external {
        require(totalFunds > 0, "No funds available");
        _to.transfer(totalFunds);
        totalFunds = 0;
    }
}

Neste exemplo, a função withdrawAllFunds não possui nenhum controle de acesso, portanto, qualquer pessoa poderia executá-la, mesmo que não seja o proprietário do contrato.

Mitigação:

  1. Implementar Modificadores de Acceso: A solução mais direta é implementar modificadores que restrinjam o acesso às funções críticas apenas a usuários específicos, como o proprietário do contrato ou uma lista de administradores. Em Solidity, isso pode ser feito com um modificador onlyOwner, que permite que apenas o proprietário do contrato execute determinadas funções.

    modifier onlyOwner() {
        require(msg.sender == owner, "Not the contract owner");
        _;
    }
    
    function withdrawAllFunds(address payable _to) external onlyOwner {
        require(totalFunds > 0, "No funds available");
        _to.transfer(totalFunds);
        totalFunds = 0;
    }

    Com esse modificador, apenas o proprietário do contrato pode chamar a função withdrawAllFunds.

  2. Usar bibliotecas de controle de acesso: Utilizar bibliotecas testadas e bem auditadas, como a OpenZeppelin AccessControl, para gerenciar permissões de forma segura e estruturada. Essas bibliotecas permitem a criação de papéis específicos e a atribuição de permissões a funções concretas.

  3. Testes e simulações: Implementar testes rigorosos que simulem ataques potenciais, nos quais usuários não autorizados tentem acessar funções críticas. Esses testes ajudam a garantir que todas as funções importantes estejam devidamente protegidas.

Last updated