Failure to Initialize (Falha ao Inicializar)
Ocorre quando um contrato não é inicializado corretamente antes de ser utilizado, o que pode fazer com que variáveis crÃticas — como o proprietário do contrato ou configurações importantes — permaneçam em um estado padrão. Isso pode permitir que qualquer usuário assuma o controle do contrato ou que o contrato funcione de maneira inesperada.
Exemplo:
Imagine que você possui um contrato inteligente que deve ser inicializado com um endereço de proprietário (owner
) que possui privilégios especiais, como a capacidade de pausar ou destruir o contrato. Se o contrato não tiver um construtor que atribua a direção do proprietário, ou se for implantado utilizando um proxy sem uma função de inicialização adequada, a variável owner
pode permanecer em um estado padrão — como o endereço 0x0
ou qualquer outro valor padrão.
contract VulnerableContract {
address public owner;
function initialize(address _owner) external {
owner = _owner;
}
function pauseContract() external {
require(msg.sender == owner, "Not the contract owner");
// Lógica para pausar o contrato
}
}
Neste exemplo, se a função initialize
não for chamada após o contrato ser implantado, a variável owner
permanecerá sem ser definida, e qualquer usuário poderá potencialmente chamar initialize
e se definir como proprietário, assumindo o controle do contrato.
Mitigação:
Uso de um construtor: Se o contrato não utilizar um padrão de proxy e for implantado diretamente, é sempre recomendável usar um constructor para inicializar variáveis crÃticas como
owner
. O construtor garante que essas variáveis sejam definidas no momento da implantação e não possam ser modificadas posteriormente.contract SecureContract { address public owner; constructor(address _owner) { owner = _owner; } function pauseContract() external { require(msg.sender == owner, "Not the contract owner"); // Lógica para pausar o contrato } }
Inicialização em proxies: Quando se utiliza um padrão de proxy para implantar contratos (um padrão comum para facilitar atualizações), é fundamental incluir uma função de inicialização que assegure que o contrato só possa ser inicializado uma única vez. Essa função deve estar protegida para que possa ser chamada apenas uma vez e não possa ser reutilizada por um atacante.
contract SecureContract { address public owner; bool private initialized; function initialize(address _owner) external { require(!initialized, "Already initialized"); owner = _owner; initialized = true; } function pauseContract() external { require(msg.sender == owner, "Not the contract owner"); // Lógica para pausar o contrato } }
Proteção contra re-inicialização: Além de garantir que a função de inicialização só possa ser executada uma vez, é possÃvel implementar um modificador que verifique se o contrato já foi inicializado antes de permitir a execução de funções crÃticas. Isso impede que um atacante tente inicializar o contrato novamente ou redefinir variáveis sensÃveis após a implantação.
modifier onlyInitialized() { require(initialized, "Contract not initialized"); _; } function pauseContract() external onlyInitialized { require(msg.sender == owner, "Not the contract owner"); // Lógica para pausar o contrato }
Last updated