Nota: Este artigo fornece uma visão geral básica dos ataques de reentrância e como eles ocorrem em contratos inteligentes, nenhuma experiência anterior em Solidity é necessária.
Visão geral do cenário Blockchain
A inovação revolucionária fornecida pela Blockchain e pelas criptomoedas gerou uma mudança de paradigma nas economias digitais. Ao fornecer uma estrutura descentralizada para transações monetárias e execução de código, a tecnologia blockchain resultou em uma ampla variedade de aplicativos e plataformas descentralizadas (DAPPs), interrompendo algumas das maiores e mais estabelecidas indústrias: finanças (DeFi), arte (NFTs) e jogos (GameFi). Tal disrupção eliminou os intermediários de uma maneira que não é mais necessário ter confiança em terceiros (aumentando os lucros para os usuários), derrubou as barreiras à entrada (blockchains são redes globais e sem necessidade de permissão) e aumentou drasticamente a eficiência das transações online (de períodos de processamento de pagamento de 3 a 5 dias para minutos).
Segurança de contratos inteligentes
Infelizmente, com todos os benefícios vêm alguns contras. Embora a natureza criptográfica das blockchains forneça um alto nível de segurança para as próprias blockchains subjacentes, a infraestrutura para aplicativos blockchain permanece embrionária, fornecendo vulnerabilidades de segurança em grande parte irrelevantes para as empresas da web 2.0. Tais vulnerabilidades resultaram em hacks (ataques na internet) sem precedentes, com ataques singulares resultando em dezenas, senão centenas de milhões de dólares sendo roubados. Somente em 2022, os hacks resultaram no roubo de mais de 2 bilhões de dólares em criptomoedas. Para entender por que os hacks de criptomoeda são tão prevalentes e prejudiciais, primeiro é necessário entender a infraestrutura on-chain dos DAPPs.
A infraestrutura de aplicativos descentralizada opera on-chain por meio de contratos inteligentes. Contratos inteligentes são transações blockchain contendo código executável que pode ser usado para criar programas automatizados. Os contratos inteligentes permitem a computação on-chain, permitindo que aplicativos descentralizados integrem processos com transferências monetárias. Apesar da utilidade e funcionalidade dos contratos inteligentes, eles apresentam uma variedade de riscos normalmente não associados aos aplicativos da web 2. Como mencionado anteriormente, as blockchains são abertas e sem necessidade de permissão de terceiros, o que significa que qualquer pessoa pode interagir com blockchains e aplicativos descentralizados. Dado que os contratos inteligentes de aplicativos descentralizados costumam ser públicos em blockchains, o código de contrato inteligente geralmente é de código aberto ou visível em exploradores de blockchain, permitindo que os usuários verifiquem a validade dos contratos com os quais estão interagindo. Tal transparência oferece benefícios, particularmente necessidade mínima de confiança em terceiros, mas também apresenta riscos. Qualquer pessoa, a qualquer momento, pode interagir com os contratos inteligentes do DAPP, permitindo que os indivíduos chamem funções e passem dados para os referidos contratos inteligentes. O código aberto e a natureza acessível dos contratos inteligentes tornam o trabalho de um hacker muito mais fácil, permitindo que eles visualizem e interajam abertamente com contratos inteligentes para lançar ataques. Essa transparência e abertura normalmente não são encontradas em aplicativos da Web 2, que podem ter processos de back-end privados e operados internamente. A gama livre de contratos inteligentes forneceu aos hackers a oportunidade de executar vários ataques, principalmente ataques de reentrância.
Ataques de reentrância
Talvez o mais infame de qualquer ataque de contrato inteligente seja o notório ataque de reentrância. Na ciência da computação, um programa é considerado reentrante se puder ser “reentrado”, o que significa que pode ser interrompido durante a execução e aceitar invocações alternativas. Isso significa que várias invocações podem ser executadas simultaneamente para produzir várias saídas, mesmo que uma chamada anterior tenha sido pausada, permitindo que programas reentrantes aceitem entradas adicionais antes de produzir uma saída anterior. No caso do Solidity, a reentrância ocorre por meio de funções de fallback. As funções de fallback são executadas quando um contrato recebe eth, mas nenhuma chamada acompanhante com um identificador de função válido, ou uma função é chamada sem entradas de dados esperadas. Em tais casos, as funções de fallback fazem sentido porque ajudam a proteger os usuários que podem interagir com um contrato inteligente incorretamente para devolver seus fundos. No entanto, as funções de fallback apresentam vários riscos. As funções de fallback podem executar lógica arbitrária, permitindo que os hackers criem funções de fallback maliciosas. Supondo que o contrato inteligente de destino permita que funções de fallback externas sejam executadas sem acompanhar mudanças imediatas no estado da blockchain, podem ocorrer ataques de reentrância. Mais notavelmente, os ataques de reentrância podem ocorrer com a função de retirada de um contrato inteligente.
Para maior clareza, vamos dar uma olhada em um exemplo. Digamos que um contrato inteligente tenha uma função de retirada com a seguinte configuração.
Embora possa parecer complicado, esta função pode ser resumida em termos de três processos:
- Verificando o saldo: uint bal = balances [msg.sender];
- Enviando o valor retirado: (bool sent, ) = msg.sender.call{value: bal} (''');
- Ajustando o saldo do usuário no contrato para refletir a retirada: Balances [msg.sender] = 0;
Todos esses processos são executados sequencialmente de 1 a 3. No entanto, uma mudança de estado só é executada após a conclusão de toda a função, o que significa que todos os três processos devem ocorrer antes que a blockchain registre uma mudança de estado. Assim, existe uma pequena janela de tempo entre o envio de fundos do contrato e o saldo de atualização do contrato, permitindo a possibilidade de um ataque de reentrância. Como mencionado anteriormente, as funções de fallback ocorrem quando o eth é recebido sem as entradas esperadas, portanto, o invasor pode configurar um contrato malicioso externo de modo que o eth recebido da retirada acione uma função de fallback. As funções de fallback também podem permitir lógica arbitrária, permitindo que um invasor configure a função de fallback como outra chamada de retirada. Essa função de fallback pode executar outra retirada antes que a atualização do contrato de destino seja balanceada. A retirada subsequente pode ainda acionar novamente a função de fallback maliciosa, permitindo efetivamente que o invasor drene o saldo do contrato de destino por meio de um ataque de reentrância recursivo. O diagrama a seguir apresenta o fluxo de trabalho exato do referido ataque de reentrância.
Impacto dos ataques de reentrância
Apesar de sua relativa simplicidade, os ataques de reentrância têm sido o vetor de ataque para vários hacks, sendo o mais infame o “The DAO Hack”. Em 2016, membros da comunidade e investidores se uniram para criar uma organização digital revolucionária utilizando a infraestrutura Ethereum. A The DAO foi a primeira iteração de DAOs, ou organizações autônomas descentralizadas, e procurou fornecer investimentos por meio de contratos inteligentes. A The DAO acumulou mais de 150 milhões de dólares em ether (vale bilhões agora), uma soma inovadora na época. No entanto, devido a vulnerabilidades no código de contrato inteligente, ocorreu um ataque de reentrância, não muito diferente do descrito neste artigo, desviando 60 milhões de dólares em ether. O ataque foi um momento crucial na história da Ethereum, resultando em um controverso _hard fork _(processo de bifurcações ou atualizações de blockchain) para recuperar os fundos perdidos. Desde então, dezenas de ataques de reentrância ocorreram em protocolos, somando-se aos danos causados pelos ataques de reentrância.
Mitigação do risco de ataque de reentrância
Apesar dos numerosos ataques de reentrância anteriores, há boas notícias: os ataques de reentrância podem ser evitados. Talvez a melhor proteção contra um ataque de reentrância seja garantir que uma atualização de estado ocorra antes de fazer qualquer chamada externa ou interagir com contratos externos. Uma atualização de estado antes da interação com contratos externos impede que uma função de fallback externa seja executada com êxito ou reentre sem que o contrato de destino seja atualizado de acordo. Por exemplo, o saldo de um invasor após uma retirada inicial seria atualizado de acordo, evitando retiradas maliciosas recursivas. Outra solução é implementar modificadores, bloqueando efetivamente uma função enquanto ela ainda está em execução para que nenhum invasor possa reentrar.
Conclusão
Apesar da variedade de ataques de reentrância anteriores, os desenvolvedores podem ter certeza de que existem soluções para evitar tais ataques. No entanto, os ataques de reentrância são apenas um exemplo de hack que podem ocorrer em contratos inteligentes. Da mesma forma, existe uma variedade de preocupações com a segurança cibernética fora dos contratos inteligentes, particularmente a segurança de chaves privadas. Além disso, muitos DAPPs incluem componentes centralizados em sua pilha de tecnologia, fornecendo outra camada de preocupações de segurança não relacionadas à blockchain. À luz das grandes quantidades de dados pessoais e dinheiro operando por meio de soluções digitais, é importante para qualquer empresa de tecnologia, seja Web 3.0 ou Web 2.0, estar ciente e se preparar adequadamente para qualquer risco de segurança cibernética.
Este artigo foi escrito por Benjamin Chai e traduzido por Marcelo Panegali.
Top comments (0)