Análise de vulnerabilidades do compilador Solidity e estratégias de mitigação
O compilador é um dos componentes fundamentais dos sistemas de computação modernos, e a sua principal função é converter o código-fonte de linguagens de programação de alto nível em código de instruções que pode ser executado pela CPU ou por uma máquina virtual.
Embora a maioria dos desenvolvedores e profissionais de segurança geralmente se concentrem mais na segurança do código do aplicativo, a segurança do próprio compilador também é igualmente importante. Como programas de computador, os compiladores também podem ter vulnerabilidades de segurança, que em alguns casos podem representar sérios riscos de segurança.
Tomando o navegador como exemplo, durante o processo de compilação e execução do código front-end JavaScript, pode haver uma exploração de vulnerabilidades do motor de análise JavaScript, permitindo que um atacante execute código remotamente ao acessar páginas maliciosas, controlando assim o navegador da vítima ou até mesmo o sistema operativo. Além disso, bugs no compilador C++ também podem causar a execução remota de código e outras consequências graves.
O compilador Solidity também apresenta vulnerabilidades de segurança. De acordo com o aviso de segurança da equipe de desenvolvimento do Solidity, várias versões do compilador Solidity contêm vulnerabilidades de segurança.
Vulnerabilidade do compilador Solidity
O papel do compilador Solidity é converter o código do contrato inteligente em código de instruções (EVM) para a Máquina Virtual Ethereum, que é empacotado e enviado para o Ethereum através de transações, e finalmente interpretado e executado pelo EVM.
É importante notar que as vulnerabilidades do compilador Solidity são diferentes das vulnerabilidades do próprio EVM. As vulnerabilidades do EVM referem-se a problemas de segurança que surgem quando a máquina virtual executa instruções, podendo afetar toda a rede Ethereum. Por outro lado, as vulnerabilidades do compilador Solidity referem-se a problemas que ocorrem ao converter Solidity em código EVM, e não afetam diretamente a rede Ethereum em si.
Uma das perigosas falhas do compilador Solidity é que pode resultar em códigos EVM gerados que não correspondem às expectativas dos desenvolvedores de contratos inteligentes. Como os contratos inteligentes na Ethereum estão frequentemente relacionados aos ativos de criptomoeda dos usuários, qualquer bug causado pelo compilador pode levar à perda de ativos dos usuários, resultando em consequências graves.
Os desenvolvedores e auditores de contratos podem se concentrar em questões de implementação da lógica do código do contrato, bem como em problemas de segurança em nível Solidity, como reentrância e estouro de inteiros. No entanto, para identificar vulnerabilidades no compilador Solidity, é difícil descobrir apenas através da auditoria da lógica do código-fonte do contrato. É necessário analisar em conjunto uma versão específica do compilador com um padrão de código específico para determinar se o contrato inteligente é afetado por vulnerabilidades do compilador.
Exemplo de vulnerabilidade do compilador Solidity
Aqui estão alguns exemplos reais de vulnerabilidades do compilador Solidity, que mostram as 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:
solidity
contrato C {
uint32 a = 0x12345678;
uint32 b = 0;
função run() retorna (uint256) {
a += 1;
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, no código gerado pelo compilador da versão vulnerável, run() retornará 1.
Esta situação inesperada, se a variável b for utilizada para validação de permissões, contabilidade de ativos, entre outros, pode levar a consequências graves.
A razão para o aparecimento desta situação é que a EVM utiliza elementos de pilha de tamanho 32 bytes, enquanto o Solidity suporta tipos de dados menores como uint32. O compilador precisa realizar operações de limpeza nos bits mais altos ao lidar com esses tipos, mas não o faz corretamente em caso de estouro de inteiro, resultando na escrita de 1 bit nos bits mais altos na variável b adjacente.
SOL-2022-4 InlineAssemblyMemorySideEffects
A vulnerabilidade existe nas versões do compilador de 0.8.13 a 0.8.15.
Considere o seguinte código:
solidity
contrato C {
function f() public pure returns (uint) {
assembly {
mstore(0, 0x42)
}
uint x;
assembly {
x := mload(0)
}
return x;
}
}
A vulnerabilidade origina-se de operações de otimização de compilação. O compilador analisa e otimiza blocos individuais de assembly; se uma operação de escrita na memória não for lida posteriormente, será removida para economizar gas. No entanto, as operações de escrita e leitura na memória no código acima estão localizadas em dois blocos de assembly diferentes, e o compilador erroneamente determina que a primeira escrita é redundante e a remove, resultando na função f() retornar 0 em vez do correto 0x42.
A vulnerabilidade afeta os compiladores das versões 0.5.8 a 0.8.16.
Considere o seguinte código:
solidity
contract C {
function f(bytes4[] calldata a) external pure returns (bytes4[] memory) {
return abi.decode(abi.encode(a), (bytes4[]));
}
}
Em condições normais, o código deve retornar a variável a de entrada. Mas na versão com vulnerabilidade, se a entrada for "aaaa", retornará um array vazio.
Isto deve-se ao fato de que o Solidity, ao realizar a operação abi.encode em arrays do tipo calldata, limpou erroneamente alguns dados, resultando na modificação de dados adjacentes, causando inconsistências nos dados após a codificação e decodificação.
É importante notar que o Solidity codifica implicitamente os parâmetros com abi.encode ao realizar chamadas externas e emitir eventos, portanto, a probabilidade de ocorrerem esse tipo de vulnerabilidades pode ser maior do que se imagina.
Sugestões de Segurança
Em relação às vulnerabilidades do compilador Solidity, apresentamos as seguintes recomendações para desenvolvedores e profissionais de segurança:
Para os desenvolvedores:
Utilize uma versão mais recente do compilador Solidity. Versões mais novas geralmente corrigem problemas de segurança conhecidos.
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, e aumentando a cobertura dos testes pode-se evitar ao máximo esses problemas.
Evite ao máximo o uso de assembly inline, operações complexas de codificação e decodificação de ABI, e não use novas funcionalidades e características experimentais de forma cega. A maioria das vulnerabilidades do compilador estão relacionadas a essas operações complexas.
Para o pessoal de segurança:
Ao auditar código Solidity, não ignore os riscos de segurança que o compilador pode introduzir.
Durante o processo de desenvolvimento interno, urge a equipe de desenvolvimento a atualizar a versão do compilador Solidity, podendo considerar a introdução de uma verificação automática da versão do compilador no processo de CI/CD.
Não é necessário se preocupar excessivamente com vulnerabilidades do compilador, a maioria das vulnerabilidades é acionada apenas em padrões de código específicos, e é necessário avaliar o impacto real com base nas circunstâncias do projeto específico.
Alguns recursos úteis:
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
O triângulo de exclamação no canto superior direito da página do código do contrato no Etherscan pode indicar vulnerabilidades de segurança na versão atual do compilador.
Em suma, as vulnerabilidades do compilador Solidity são um risco de segurança que não pode ser ignorado no desenvolvimento de contratos inteligentes. Os desenvolvedores e os profissionais de segurança devem estar alertas e tomar as medidas apropriadas para reduzir as potenciais ameaças apresentadas por essas vulnerabilidades.
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.
10 gostos
Recompensa
10
8
Partilhar
Comentar
0/400
BlockDetective
· 07-07 07:59
Mais uma vez caí em uma armadilha, gkd atualização.
Ver originalResponder0
liquidation_surfer
· 07-06 14:45
Mais um monte de bugs apareceram.
Ver originalResponder0
GasFeeCrier
· 07-04 08:26
Versão oficial atualizada todos os dias quem quem quem
Ver originalResponder0
DoomCanister
· 07-04 08:24
Vai consertar o código rapidamente.
Ver originalResponder0
Token_Sherpa
· 07-04 08:23
ngmi se não estiveres a auditar as versões do teu compilador tbh... já vi demasiadas histórias de rekt
Ver originalResponder0
PonziDetector
· 07-04 08:21
É novamente hora de caça aos bugs, a minha atividade favorita.
Análise de vulnerabilidades do compilador Solidity e estratégias de mitigação
Análise de vulnerabilidades do compilador Solidity e estratégias de mitigação
O compilador é um dos componentes fundamentais dos sistemas de computação modernos, e a sua principal função é converter o código-fonte de linguagens de programação de alto nível em código de instruções que pode ser executado pela CPU ou por uma máquina virtual.
Embora a maioria dos desenvolvedores e profissionais de segurança geralmente se concentrem mais na segurança do código do aplicativo, a segurança do próprio compilador também é igualmente importante. Como programas de computador, os compiladores também podem ter vulnerabilidades de segurança, que em alguns casos podem representar sérios riscos de segurança.
Tomando o navegador como exemplo, durante o processo de compilação e execução do código front-end JavaScript, pode haver uma exploração de vulnerabilidades do motor de análise JavaScript, permitindo que um atacante execute código remotamente ao acessar páginas maliciosas, controlando assim o navegador da vítima ou até mesmo o sistema operativo. Além disso, bugs no compilador C++ também podem causar a execução remota de código e outras consequências graves.
O compilador Solidity também apresenta vulnerabilidades de segurança. De acordo com o aviso de segurança da equipe de desenvolvimento do Solidity, várias versões do compilador Solidity contêm vulnerabilidades de segurança.
Vulnerabilidade do compilador Solidity
O papel do compilador Solidity é converter o código do contrato inteligente em código de instruções (EVM) para a Máquina Virtual Ethereum, que é empacotado e enviado para o Ethereum através de transações, e finalmente interpretado e executado pelo EVM.
É importante notar que as vulnerabilidades do compilador Solidity são diferentes das vulnerabilidades do próprio EVM. As vulnerabilidades do EVM referem-se a problemas de segurança que surgem quando a máquina virtual executa instruções, podendo afetar toda a rede Ethereum. Por outro lado, as vulnerabilidades do compilador Solidity referem-se a problemas que ocorrem ao converter Solidity em código EVM, e não afetam diretamente a rede Ethereum em si.
Uma das perigosas falhas do compilador Solidity é que pode resultar em códigos EVM gerados que não correspondem às expectativas dos desenvolvedores de contratos inteligentes. Como os contratos inteligentes na Ethereum estão frequentemente relacionados aos ativos de criptomoeda dos usuários, qualquer bug causado pelo compilador pode levar à perda de ativos dos usuários, resultando em consequências graves.
Os desenvolvedores e auditores de contratos podem se concentrar em questões de implementação da lógica do código do contrato, bem como em problemas de segurança em nível Solidity, como reentrância e estouro de inteiros. No entanto, para identificar vulnerabilidades no compilador Solidity, é difícil descobrir apenas através da auditoria da lógica do código-fonte do contrato. É necessário analisar em conjunto uma versão específica do compilador com um padrão de código específico para determinar se o contrato inteligente é afetado por vulnerabilidades do compilador.
Exemplo de vulnerabilidade do compilador Solidity
Aqui estão alguns exemplos reais de vulnerabilidades do compilador Solidity, que mostram as 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:
solidity contrato C { uint32 a = 0x12345678; uint32 b = 0; função run() retorna (uint256) { a += 1; 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, no código gerado pelo compilador da versão vulnerável, run() retornará 1.
Esta situação inesperada, se a variável b for utilizada para validação de permissões, contabilidade de ativos, entre outros, pode levar a consequências graves.
A razão para o aparecimento desta situação é que a EVM utiliza elementos de pilha de tamanho 32 bytes, enquanto o Solidity suporta tipos de dados menores como uint32. O compilador precisa realizar operações de limpeza nos bits mais altos ao lidar com esses tipos, mas não o faz corretamente em caso de estouro de inteiro, resultando na escrita de 1 bit nos bits mais altos na variável b adjacente.
SOL-2022-4 InlineAssemblyMemorySideEffects
A vulnerabilidade existe nas versões do compilador de 0.8.13 a 0.8.15.
Considere o seguinte código:
solidity contrato C { function f() public pure returns (uint) { assembly { mstore(0, 0x42) } uint x; assembly { x := mload(0) } return x; } }
A vulnerabilidade origina-se de operações de otimização de compilação. O compilador analisa e otimiza blocos individuais de assembly; se uma operação de escrita na memória não for lida posteriormente, será removida para economizar gas. No entanto, as operações de escrita e leitura na memória no código acima estão localizadas em dois blocos de assembly diferentes, e o compilador erroneamente determina que a primeira escrita é redundante e a remove, resultando na função f() retornar 0 em vez do correto 0x42.
SOL-2022-6 AbiReencodingHeadOverflowWithStaticArrayCleanup
A vulnerabilidade afeta os compiladores das versões 0.5.8 a 0.8.16.
Considere o seguinte código:
solidity contract C { function f(bytes4[] calldata a) external pure returns (bytes4[] memory) { return abi.decode(abi.encode(a), (bytes4[])); } }
Em condições normais, o código deve retornar a variável a de entrada. Mas na versão com vulnerabilidade, se a entrada for "aaaa", retornará um array vazio.
Isto deve-se ao fato de que o Solidity, ao realizar a operação abi.encode em arrays do tipo calldata, limpou erroneamente alguns dados, resultando na modificação de dados adjacentes, causando inconsistências nos dados após a codificação e decodificação.
É importante notar que o Solidity codifica implicitamente os parâmetros com abi.encode ao realizar chamadas externas e emitir eventos, portanto, a probabilidade de ocorrerem esse tipo de vulnerabilidades pode ser maior do que se imagina.
Sugestões de Segurança
Em relação às vulnerabilidades do compilador Solidity, apresentamos as seguintes recomendações para desenvolvedores e profissionais de segurança:
Para os desenvolvedores:
Para o pessoal de segurança:
Alguns recursos úteis:
Em suma, as vulnerabilidades do compilador Solidity são um risco de segurança que não pode ser ignorado no desenvolvimento de contratos inteligentes. Os desenvolvedores e os profissionais de segurança devem estar alertas e tomar as medidas apropriadas para reduzir as potenciais ameaças apresentadas por essas vulnerabilidades.