Nesse artigo iremos aprender a como um contrato malicioso consegue ocultar seu script malicioso e como previnir um ataque em seu contrato inteligente.
Vulnerabilidade
No Solidity qualquer endereço pode ser convertido em contrato específico, mesmo que o contrato no endereço não seja o que está sendo lançado.
Isso pode ser explorado para ocultar códigos maliciosos. Vamos ver como.
Como funciona:
Digamos que Alice possa ver o código de Foo e Bar, mas não de Mal.
É óbvio para Alice que Foo.callBar()
executa o código dentro de Bar.log()
.
No entanto, Eve implanta Foo com o endereço de Mal, de modo que chamar Foo.callBar()
irá realmente executar o código em Mal.
- Eve implanta Mal
- Eve implanta Foo com o endereço de Mal
- Alice chama
Foo.callBar()
depois de ler o código e julgar que é seguro para interagir. - Embora Alice esperasse que
Bar.log()
fosse executado,Mal.log()
foi executado.
O que aconteceu?
Alice foi levada a interagir com o contrato Mal, mesmo após revisar o contrato Bar e entender que o script estava correto.
Devido a tática de Eve de esconder o contrato Mal atrás do contrato Bar, ocasionando assim uma interação com possível script malicioso como podemos ver abaixo.
// SPDX-License-Identifier: MITpragma solidity ^0.8.13;contract Foo {Bar bar;constructor(address _bar) {bar = Bar(_bar);}function callBar() public {bar.log();}}contract Bar {event Log(string message);function log() public {emit Log("Bar foi chamado");}}// Este código está oculto em um arquivo separadocontract Mal {event Log(string message);// function () external {// emit Log("Mal foi chamado");// }// Na verdade podemos executar o mesmo exploit mesmo que esta função// não exista usando o fallbackfunction log() public {emit Log("Mal foi chamado");}}
Técnicas Preventivas
- Inicialize um novo contrato dentro do construtor
- Fazer com que o endereço do contrato externo seja
public
para que o código do contrato externo possa ser revisado
Bar public bar;constructor() public {bar = new Bar();}