Análise detalhada das vulnerabilidades do compilador Solidity e estratégias de prevenção

Análise de Vulnerabilidades do Compilador Solidity e Estratégias de Resposta

O compilador é uma das partes fundamentais dos sistemas modernos de computação. É um programa de computador cuja função principal é converter o código fonte de linguagens de programação de alto nível, que são fáceis para os humanos entenderem e escreverem, em códigos de instrução executáveis pela CPU ou por uma máquina virtual de bytecode.

A maioria dos desenvolvedores e profissionais de segurança geralmente se concentra na segurança do código das aplicações, mas pode negligenciar a segurança do próprio compilador. Na verdade, o compilador, como um programa de computador, também possui vulnerabilidades de segurança, e essas vulnerabilidades podem representar riscos de segurança graves em certas circunstâncias. Por exemplo, durante o processo de compilação e interpretação do código Javascript no lado do cliente, pode haver uma exploração de vulnerabilidades do mecanismo de análise de Javascript, fazendo com que usuários que acessam páginas web maliciosas sejam atacados por invasores que utilizam essas vulnerabilidades para realizar a execução remota de código, e assim, obter controle sobre o navegador da vítima ou até mesmo sobre o sistema operacional.

O compilador Solidity não é exceção, existem vulnerabilidades de segurança em várias versões diferentes.

Vulnerabilidades do compilador Solidity

O papel do compilador Solidity é converter o código de contratos inteligentes escrito pelos desenvolvedores em códigos de instrução do Ethereum Virtual Machine (EVM). Esses códigos de instrução EVM são empacotados em transações e enviados para o Ethereum, onde são finalmente analisados e executados pelo EVM.

É necessário distinguir entre as vulnerabilidades do compilador Solidity e as vulnerabilidades da própria EVM. As vulnerabilidades da EVM referem-se a problemas de segurança que surgem quando a máquina virtual executa instruções. Como os atacantes podem fazer upload de qualquer código para o Ethereum, esse código acabará sendo executado em cada programa cliente P2P do Ethereum. Se houver vulnerabilidades de segurança na EVM, isso afetará toda a rede Ethereum, podendo causar um ataque de negação de serviço (DoS) e até mesmo levar à completa tomada da cadeia pelos atacantes. No entanto, devido ao design relativamente simples da própria EVM e ao fato de que o código central não é atualizado com frequência, a probabilidade de surgirem problemas como os mencionados é relativamente baixa.

Vulnerabilidades do compilador Solidity referem-se a problemas que ocorrem quando o compilador converte Solidity em código EVM. Ao contrário de cenários como os navegadores que compilam e executam Javascript no computador do cliente do usuário, o processo de compilação do Solidity ocorre apenas no computador do desenvolvedor de contratos inteligentes e não é executado na Ethereum. Portanto, as vulnerabilidades do compilador Solidity não afetam diretamente a rede Ethereum em si.

Uma das principais ameaças das vulnerabilidades do compilador Solidity é que podem levar a uma inconsistência entre o código EVM gerado e as expectativas do desenvolvedor de contratos inteligentes. Como os contratos inteligentes na Ethereum geralmente envolvem os ativos de criptomoeda dos usuários, qualquer bug nos contratos inteligentes causado pelo compilador pode resultar em perdas de ativos dos usuários, gerando consequências graves.

Os desenvolvedores e auditores de contratos podem se concentrar em problemas de implementação lógica do código do contrato, bem como em questões de segurança no nível do Solidity, como reentrância e estouro de inteiros. No entanto, é difícil descobrir vulnerabilidades do compilador Solidity apenas por meio da auditoria da lógica do código-fonte do contrato. É necessário analisar conjuntamente a versão específica do compilador e padrões de código específicos para determinar se o contrato inteligente é afetado por vulnerabilidades do compilador.

Análise de vulnerabilidades do compilador Solidity e medidas de resposta

Exemplo de vulnerabilidade do compilador Solidity

Abaixo estão alguns exemplos reais de vulnerabilidades do compilador Solidity, mostrando suas formas específicas, causas e danos.

SOL-2016-9 HighOrderByteCleanStorage

A vulnerabilidade existe em versões anteriores do compilador Solidity (>=0.1.6 <0.4.4).

Considere o seguinte código:

solidez contrato C { uint32 a = 0x1234; uint32 b = 0; function f() public { a += 1; } function run() public view returns (uint) { return b; } }

A variável de armazenamento b não foi modificada, portanto a função run() deve retornar o valor padrão 0. No entanto, na versão do compilador com vulnerabilidades, o código gerado pela função run() retornará 1.

Sem compreender a vulnerabilidade do compilador, é difícil para um desenvolvedor comum detectar os bugs no código acima apenas através de uma simples revisão de código. Este exemplo de código é relativamente simples e pode não causar danos particularmente graves. No entanto, se a variável b for usada para validação de permissões, contabilidade de ativos, etc., essa inconsistência em relação ao esperado pode ter consequências muito graves.

A razão para a ocorrência desse fenômeno anômalo é que o EVM utiliza uma máquina virtual baseada em pilha, onde cada elemento da pilha tem um tamanho de 32 bytes (, ou seja, o tamanho de uma variável uint256 ). Por outro lado, cada slot de armazenamento subjacente (storage) também tem um tamanho de 32 bytes. No nível da linguagem Solidity, são suportados tipos de dados menores que 32 bytes, como uint32, e o compilador, ao processar variáveis desse tipo, precisa realizar operações de limpeza adequadas nos bits altos ( clean up ) para garantir a correção dos dados. Na situação descrita, quando a adição resulta em um estouro de inteiro, o compilador não limpou corretamente os bits altos do resultado, levando ao fato de que o bit 1 alto foi escrito no storage, sobrepondo a variável a a variável b, alterando o valor da variável b para 1.

SOL-2022-4 InlineAssemblyMemorySideEffects

A vulnerabilidade existe nas versões do compilador >=0.8.13 <0.8.15. Considere o seguinte código:

solidez contrato C { function f() public pure returns (uint) { montagem { mstore(0, 0x42) } uint x; assembly { x := mload(0) } return x; } }

O compilador Solidity não se limita a uma simples tradução ao converter a linguagem Solidity em código EVM. Ele também realiza uma análise aprofundada do fluxo de controle e dos dados, implementando vários processos de otimização de compilação, a fim de reduzir o tamanho do código gerado e otimizar o consumo de gás durante o processo de execução. Essas operações de otimização são comuns em compiladores de várias linguagens de alto nível, mas devido à complexidade das situações a serem consideradas, é fácil que ocorram bugs ou vulnerabilidades de segurança.

A vulnerabilidade do código acima decorre desse tipo de operação de otimização. Considere a seguinte situação: se houver um código em uma função que modifica dados no endereço de memória 0, mas não houver nenhum outro lugar no código que utilize esses dados, então, na verdade, o código que modifica a memória 0 pode ser removido diretamente, economizando gás e sem afetar a lógica subsequente do programa.

Esta estratégia de otimização em si não tem problema, mas na implementação do código do compilador Solidity, tal otimização é aplicada apenas dentro de um único bloco de assembly. No código de exemplo acima, a escrita e o acesso à memória 0 ocorrem em dois blocos de assembly diferentes, enquanto o compilador analisou e otimizou apenas o bloco de assembly individual. Como não há operações de leitura após a escrita na memória 0 no primeiro bloco de assembly, a instrução de escrita é considerada redundante e será removida, resultando em um bug. Na versão com vulnerabilidades, a função f( retornará o valor 0, quando na verdade o código acima deveria retornar o valor correto 0x42.

) SOL-2022-6 AbiReencodingHeadOverflowWithStaticArrayCleanup

A vulnerabilidade afeta compiladores da versão >= 0.5.8 < 0.8.16. Considere o seguinte código:

solidity contrato C { function f###uint8( calldata a[4] public pure returns )string memory( { return string)abi.encode(a(); } }

Normalmente, a variável a retornada pelo código acima deve ser "aaaa". Mas na versão com vulnerabilidades, irá retornar uma string vazia "".

A causa da vulnerabilidade é que o Solidity, ao realizar a operação abi.encode em arrays do tipo calldata, faz uma limpeza incorreta de alguns dados, levando à modificação de outros dados adjacentes, resultando em inconsistências nos dados após a codificação e decodificação.

É importante notar que, ao realizar chamadas externas e emitir eventos, o Solidity codifica implicitamente os parâmetros com abi.encode. Portanto, a probabilidade de ocorrência do código de vulnerabilidade mencionado é maior do que a que se pode imaginar.

![Análise de vulnerabilidades do compilador Solidity e medidas de resposta])https://img-cdn.gateio.im/webp-social/moments-c97428f89ed62d5ad8551cdb2ba30867.webp(

Sugestões de Segurança

Com base na análise do modelo de ameaça de vulnerabilidades do compilador Solidity e na revisão de vulnerabilidades históricas, são apresentadas as seguintes recomendações para desenvolvedores e profissionais de segurança.

Para os desenvolvedores:

  • Utilize uma versão mais recente do compilador Solidity. Embora novas versões possam também introduzir novos problemas de segurança, os problemas de segurança conhecidos geralmente são menos comuns em versões mais antigas.

  • Melhorar os casos de teste unitário. A maioria dos bugs a nível de compilador pode resultar em resultados de execução de código que não correspondem às expectativas. Este tipo de problema é difícil de detectar através de revisões de código, mas pode ser facilmente exposto na fase de testes. Assim, ao aumentar a cobertura de código, é possível minimizar este tipo de problemas.

  • Evite o uso de assembly embutido, operações complexas como codificação e decodificação de ABI para arrays multidimensionais e estruturas complexas sem uma necessidade clara, evitando a busca por exibições desnecessárias ao usar novos recursos da linguagem e funcionalidades experimentais. De acordo com a análise de vulnerabilidades históricas, a maioria das falhas está relacionada a operações como assembly embutido e codificadores de ABI. Os compiladores realmente têm mais probabilidade de apresentar bugs ao lidar com características complexas da linguagem. Por outro lado, os desenvolvedores também tendem a cometer erros ao usar novos recursos, levando a problemas de segurança.

Para a segurança:

  • Ao realizar uma auditoria de segurança ao código Solidity, não negligencie os riscos de segurança que o compilador Solidity pode introduzir. O item correspondente na Classificação de Fraquezas de Contrato Inteligente)SWC( é SWC-102: Versão do Compilador Obsoleta.

  • No processo de desenvolvimento interno do SDL, instar a equipa de desenvolvimento a atualizar a versão do compilador Solidity, e considerar a introdução de uma verificação automática da versão do compilador no processo de CI/CD.

  • Mas não é necessário entrar em pânico excessivo com as vulnerabilidades do compilador, a maioria das vulnerabilidades do compilador só é ativada em padrões de código específicos, e não é garantido que contratos compilados com versões vulneráveis do compilador apresentem riscos de segurança. O impacto real na segurança precisa ser avaliado de acordo com a situação do projeto.

Alguns recursos práticos:

  • Alertas de segurança publicados regularmente pela equipe Solidity:

  • Lista de bugs atualizada regularmente no repositório oficial do Solidity:

  • Lista de bugs do compilador de várias versões:

  • No Etherscan, o símbolo de triângulo com ponto de exclamação no canto superior direito da página de Código do Contrato pode indicar vulnerabilidades de segurança existentes na versão atual do compilador.

Resumo

Este artigo começa com os conceitos básicos de compiladores, apresenta vulnerabilidades do compilador Solidity e analisa os riscos de segurança que podem surgir no ambiente de desenvolvimento Ethereum real, fornecendo, por fim, várias recomendações práticas para desenvolvedores e profissionais de segurança.

![Análise de Vulnerabilidades do Compilador Solidity e Medidas de Resposta])https://img-cdn.gateio.im/webp-social/moments-84f5083d8748f2aab71fd92671d999a7.webp(

ETH0.3%
Ver original
Esta página pode conter conteúdos de terceiros, que são fornecidos apenas para fins informativos (sem representações/garantias) e não devem ser considerados como uma aprovação dos seus pontos de vista pela Gate, nem como aconselhamento financeiro ou profissional. Consulte a Declaração de exoneração de responsabilidade para obter mais informações.
  • Recompensa
  • 5
  • Partilhar
Comentar
0/400
ZenZKPlayervip
· 15h atrás
A vulnerabilidade de estouro é um pouco chata.
Ver originalResponder0
OffchainWinnervip
· 20h atrás
Escrever código não dá tempo para se preocupar com bugs.
Ver originalResponder0
OnchainSnipervip
· 20h atrás
Compilador falhou? Já encontrei isso antes.
Ver originalResponder0
UnluckyValidatorvip
· 20h atrás
Os compiladores têm falhas, assustando as pessoas.
Ver originalResponder0
LiquiditySurfervip
· 20h atrás
Chame o desenvolvedor para corrigir rapidamente a vulnerabilidade.
Ver originalResponder0
Negocie cripto em qualquer lugar e a qualquer hora
qrCode
Digitalizar para transferir a aplicação Gate
Novidades
Português (Portugal)
  • 简体中文
  • English
  • Tiếng Việt
  • 繁體中文
  • Español
  • Русский
  • Français (Afrique)
  • Português (Portugal)
  • Bahasa Indonesia
  • 日本語
  • بالعربية
  • Українська
  • Português (Brasil)