Análise de vulnerabilidades do compilador Solidity e estratégias de mitigação

Análise detalhada das vulnerabilidades do compilador Solidity e estratégias de resposta

O compilador é uma das partes fundamentais dos sistemas de computação modernos. É um programa de computador cuja função principal é converter o código fonte de linguagens de programação de alto nível em códigos de instrução que podem ser executados pela CPU da máquina ou por uma máquina virtual.

Embora a maioria dos desenvolvedores e profissionais de segurança normalmente se concentrem na segurança do código do aplicativo, a segurança do próprio compilador também é importante. Como programas de computador, os compiladores podem ter vulnerabilidades de segurança, que em certos casos podem representar riscos sérios à segurança. Por exemplo, ao compilar e analisar o código JavaScript do front-end, os navegadores podem ser explorados pelos atacantes devido a vulnerabilidades no motor de análise JavaScript quando os usuários acessam páginas web maliciosas, levando, em última instância, ao controle do navegador da vítima ou até mesmo do sistema operacional.

Os compiladores Solidity também apresentam vulnerabilidades de segurança. De acordo com o aviso de segurança da equipe de desenvolvimento do Solidity, problemas de segurança foram encontrados em várias versões diferentes dos compiladores Solidity.

Vulnerabilidade do compilador Solidity

O principal objetivo do compilador Solidity é converter o código do contrato inteligente em código de instruções da máquina virtual Ethereum (EVM). Esses códigos de instrução EVM são empacotados e enviados para o Ethereum através de transações, sendo finalmente analisados e executados pela EVM.

É importante notar que as vulnerabilidades do compilador Solidity são diferentes das 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, se houver uma vulnerabilidade de segurança na EVM, isso afetará toda a rede Ethereum, podendo resultar em negação de serviço (DoS) ou até mesmo em toda a blockchain sendo assumida por atacantes. No entanto, o design da EVM é relativamente simples, as atualizações do código central não são frequentes, portanto, a probabilidade de tais problemas ocorrerem é baixa.

As vulnerabilidades do compilador Solidity referem-se a problemas que ocorrem quando o compilador converte o código Solidity em código EVM. Ao contrário da situação em que o navegador compila e executa JavaScript no 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 é a possibilidade de que o código EVM gerado não corresponda às expectativas do desenvolvedor. Como os contratos inteligentes na Ethereum geralmente envolvem os ativos de criptomoeda dos usuários, quaisquer bugs nos contratos causados pelo compilador podem resultar em perdas de ativos dos usuários, com consequências graves.

Os desenvolvedores e auditores de contratos podem se concentrar principalmente em questões de implementação de lógica de código de contratos, bem como em problemas de segurança em nível de Solidity, como reentrância e estouro de inteiros. No entanto, as vulnerabilidades de compiladores muitas vezes são difíceis de descobrir apenas auditando o código-fonte do contrato. É necessário analisar em conjunto 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 = 0x12345678; uint32 b = 0; function f() public { a = a + 1; } função run() público view retorna (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. Mas no código gerado pela versão vulnerável do compilador, run() retornará 1.

Sem entender a vulnerabilidade do compilador, é difícil para um desenvolvedor comum detectar esse bug apenas com uma simples revisão de código. Embora este exemplo seja relativamente simples e não cause consequências particularmente graves, se a variável b for utilizada para validação de permissões, contabilidade de ativos, entre outros, essa inconsistência em relação ao esperado pode levar a consequências muito sérias.

A razão para esse fenômeno é que o EVM usa uma máquina virtual baseada em pilha, onde cada elemento da pilha tem 32 bytes de tamanho (, ou seja, o tamanho da variável uint256 ). Por outro lado, cada slot de armazenamento subjacente também tem 32 bytes de tamanho. A linguagem Solidity suporta tipos de dados menores que 32 bytes, como uint32, e o compilador, ao processar esses tipos, precisa realizar operações de limpeza apropriadas em seus bits mais altos ( clean up ) para garantir a correção dos dados. Na situação descrita, quando a adição resulta em um estouro inteiro, o compilador não fez a limpeza correta dos bits mais altos do resultado, levando a que o bit 1 do alto fosse escrito no armazenamento, eventualmente sobrescrevendo a variável a que vem depois da variável b, fazendo com que o valor da variável b fosse alterado 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:

solidity contrato C { função f() pública pura retorna (uint) { assembly { mstore(0, 0x42) } uint x; assembly { x := mload(0) } return x; } }

O compilador Solidity, ao converter a linguagem Solidity em código EVM, não realiza apenas uma tradução simples, mas também realiza uma análise aprofundada do fluxo de controle e dos dados, implementando várias otimizações de compilação para reduzir o tamanho do código gerado e otimizar o consumo de gas durante o processo de execução. Esse tipo de otimização é comum em compiladores de várias linguagens de alto nível, mas devido à complexidade das situações a serem consideradas, pode facilmente resultar em bugs ou vulnerabilidades de segurança.

A vulnerabilidade do código acima decorre deste tipo de operação de otimização. Se existir código em uma função que modifica dados no deslocamento zero da memória, mas que não usa esses dados posteriormente, então é possível remover diretamente o código que modifica a memória zero, economizando gás, sem afetar a lógica do programa subsequente.

Esta estratégia de otimização em si não tem problemas, mas na implementação específica do compilador Solidity, esse tipo de otimização é aplicado apenas a um único bloco de assembly. No código PoC mencionado, as operações de escrita e acesso à memória 0 estão em dois blocos de assembly diferentes, e o compilador analisou e otimizou apenas o bloco de assembly separado. Como não há operações de leitura após a escrita na memória 0 no primeiro bloco de assembly, o compilador considera que essa instrução de escrita é redundante e a remove, resultando em um bug. Na versão vulnerável, a função f() retornará o valor 0, quando na verdade o valor de retorno correto deveria ser 0x42.

SOL-2022-6 AbiReencodingHeadOverflowWithStaticArrayCleanup

A vulnerabilidade afeta compiladores da versão >= 0.5.8 e < 0.8.16.

Considere o seguinte código:

solidity contract C { função f(string[1] calldata a) pública pura retorna (string memória) { return abi.decode(abi.encode(a), (string[1]))[0]; } }

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

A causa da vulnerabilidade é que o Solidity, ao realizar a operação abi.encode em arrays do tipo calldata, limpou erroneamente alguns dados, resultando na modificação de outros dados adjacentes, o que causou a inconsistência dos 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 usando abi.encode, portanto, a probabilidade de ocorrer o código de vulnerabilidade mencionado é maior do que a intuição sugere.

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

Sugestões de Segurança

Face às ameaças das vulnerabilidades do compilador Solidity, são apresentadas as seguintes recomendações para desenvolvedores e profissionais de segurança:

Para desenvolvedores:

  • Use uma versão mais recente do compilador Solidity. Embora novas versões possam introduzir novos problemas de segurança, elas geralmente têm menos problemas de segurança conhecidos do que versões mais antigas.

  • Melhorar os casos de teste unitário. A maioria dos bugs a nível de compilador pode levar a 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 é fácil de expor na fase de testes. Aumentar a cobertura de código pode evitar ao máximo este tipo de problema.

  • Tente evitar o uso de assembly inline, codificação e decodificação ABI para arrays multidimensionais e estruturas complexas, e evite usar novas características da linguagem e funcionalidades experimentais sem uma necessidade clara. A maioria das vulnerabilidades históricas está relacionada a operações como assembly inline e codificadores ABI. O compilador é mais propenso a bugs ao lidar com características complexas da linguagem. Por outro lado, os desenvolvedores também podem cometer erros ao usar novas características, levando a problemas de segurança.

Para o pessoal de segurança:

  • Ao realizar auditorias de segurança em códigos Solidity, não ignore os riscos de segurança que podem ser introduzidos pelo compilador. O item de verificação correspondente na Classificação de Fraquezas em Smart Contracts(SWC) é SWC-102: Versão de Compilador Desatualizada.

  • No processo de desenvolvimento interno do SDL, encorajar a equipe de desenvolvimento a atualizar a versão do compilador Solidity e considerar a introdução de verificações automáticas para a versão do compilador no processo CI/CD.

  • Mas não é necessário entrar em pânico excessivo sobre vulnerabilidades do compilador; a maioria das vulnerabilidades do compilador só é ativada em padrões de código específicos, e não significa que contratos compilados com versões vulneráveis do compilador apresentem necessariamente riscos de segurança. O impacto real na segurança deve ser avaliado com base nas circunstâncias do projeto.

Alguns recursos úteis:

  • Publicações de Alertas de Segurança do time Solidity
  • Lista de bugs atualizada regularmente no repositório oficial do Solidity
  • Lista de bugs das várias versões do compilador. Pode-se introduzir uma verificação automática da versão do compilador no processo de CI/CD, alertando sobre as vulnerabilidades de segurança existentes na versão atual.
  • No Etherscan, o triângulo de ponto de exclamação no canto superior direito da página do código do contrato pode indicar vulnerabilidades de segurança existentes na versão atual do compilador.

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

Resumo

Este artigo começa com os conceitos básicos de compiladores, introduzindo as vulnerabilidades do compilador Solidity, analisando os riscos de segurança que podem surgir no ambiente de desenvolvimento Ethereum real, e fornecendo algumas recomendações práticas de segurança para desenvolvedores e profissionais de segurança. Ao compreender e dar importância às vulnerabilidades do compilador, é possível garantir de forma mais abrangente a segurança dos contratos inteligentes.

Ver original
This page may contain third-party content, which is provided for information purposes only (not representations/warranties) and should not be considered as an endorsement of its views by Gate, nor as financial or professional advice. See Disclaimer for details.
  • Recompensa
  • 9
  • Partilhar
Comentar
0/400
DAOplomacyvip
· 07-11 19:33
sem dúvida outra implementação sub-ótima do ponto de vista da governança...
Ver originalResponder0
LightningLadyvip
· 07-11 19:11
O que é que há de mal em termos mais vulnerabilidades de compilação?
Ver originalResponder0
SandwichDetectorvip
· 07-10 06:32
Então não é isso que fazemos?
Ver originalResponder0
GateUser-00be86fcvip
· 07-08 20:59
Os compiladores também precisam de auditoria.
Ver originalResponder0
CryptoTherapistvip
· 07-08 20:58
vamos tirar um momento de atenção plena para processar essa ansiedade de compilador... parece um trauma de sistema clássico, para ser sincero
Ver originalResponder0
CryptoPhoenixvip
· 07-08 20:56
O código-fonte é mais original do que a origem. O que cai, acabará por renascer.
Ver originalResponder0
OnlyOnMainnetvip
· 07-08 20:50
Mais uma vez a codificação vai dar trabalho ao cérebro.
Ver originalResponder0
FrogInTheWellvip
· 07-08 20:47
Ainda bem que agora não se escreve código em sol.
Ver originalResponder0
GasGuzzlervip
· 07-08 20:30
O Vulgo Dog vai começar a chamar pessoas para fazer auditoria novamente.
Ver originalResponder0
Ver mais
  • Pino
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)