Início Artigos

Análise da Lista de verificação de Solodit: Negação do Ataque de Serviço Parte 2

2025-04-15

Análise da Lista de Verificação de Solodit (2): Negação de Ataque do Serviço Parte 2

Aprenda a evitar ataques de negação de serviço (DOS) em contratos inteligentes, garantindo que as filas sejam seguras, lidando com baixos tokens decimais e gerenciando com segurança chamadas externas.

Bem -vindo de volta à série Solodit Checklist Resolution Series. Continuaremos a explorar as listas de verificação de auditoria do Solodit Smart Contract , concentrando -se em estratégias práticas para escrever contratos inteligentes seguros e resilientes.

Esta lista de verificação ajuda a identificar possíveis vulnerabilidades e implementar medidas proativas de segurança. Na seção anterior " Resolução da Lista de Verificação Solodit (1) ", examinamos três listas de verificação ( padrão de extração, quantidade mínima de transação e lista negra ) relacionadas a um ataque de negação de serviço (DOS) e forneceu soluções para desenvolvedores. Se você ainda não leu, recomendo verificar o artigo antes de continuar.

Neste artigo, discutiremos outros três itens na lista de verificação, concentrando -se novamente nos ataques do DOS. Vamos mergulhar nas vulnerabilidades de manuseio da fila , os desafios colocados por baixos tokens decimais e a importância de lidar com chamadas de contrato externas com segurança .

Para obter a melhor experiência, abra uma tag Solodit Checklist para referência.

Breve visão geral

Aqui está o que discutiremos hoje:

  • SOL-AM-DOSA-4: Bloqueio de manuseio da fila : esse problema ocorre quando um invasor manipula a fila para pausar ou interromper suas operações, resultando em DOS. Veremos como os atacantes podem destruir filas de processamento.

  • SOL-AM-DOSA-5: Baixo tokens decimais : problemas que ocorrem ao lidar com tokens com casas decimais baixas. O cálculo, especialmente a divisão, pode ser truncado a zero, resultando em comportamento inesperado e prejudicial. Esses tokens de baixa precisão podem causar problemas com a divisão inteira, interferindo assim nas principais funções.

  • SOL-AM-DOSA-6: Chamadas externas inseguras : exploraremos como confiar em contratos externos sem tratamento adequado de erros para criar vulnerabilidades. Quando a falha de uma chamada externa não é tratada corretamente, pode fazer com que todo o contrato recue .

Os ataques do mundo real provam o potencial dano que essas vulnerabilidades podem causar. O projeto sofreu grandes perdas devido a negligência aparentemente menor.

As listas de verificação de solodit são baseadas em descobertas de auditoria, relatórios de recompensas de vulnerabilidades e eventos do mundo real. Ao estudar essas listas de verificação, você pode aprender com os erros do passado e melhorar a segurança do seu código .

Agora, vejamos cada item de verificação um por um através do código de amostra. Esses exemplos foram simplificados para destacar as principais vulnerabilidades.

SOL-AM-DOSA-4: Um bloco de invasor pode impedir o processamento da fila para causar interrupções no serviço?

Problema : se seu contrato inteligente depende de uma fila para processamento de tarefas, um invasor poderá manipular um estado específico na fila para evitar o processamento correto.

Pergunta da lista de verificação : "Um bloqueio de invasor pode impedir o processamento da fila para causar interrupções no serviço?"

Solução : Seu mecanismo de manuseio da fila requer poderosos mecanismos de manuseio de erros e fallback para garantir que os problemas possam continuar sendo processados, mesmo que ocorram.

Exemplo :

Considere um exemplo de extração de uma fila:

  1. O usuário solicita a extração e alguns sinalizadores indicam que a solicitação está ativa.

  2. O invasor pode usar a função resetUserStatus após a extração ser criada para impedir a mesma operação de outros usuários.

 // 易受攻击的函数:可以被利用function resetUserStatus() external { // 任何人在仍然处于队列中的情况下都可以重置他们的状态withdrawalRequested[msg.sender] = false; // 注意:用户没有被移出队列! } // 处理队列中的下一次提取function processNextWithdrawal() external { require(withdrawalQueue.length > currentIndex, "没有可处理的提取"); // 获取下一次提取Withdrawal memory withdrawal = withdrawalQueue[currentIndex]; // 可被攻击者利用:此检查可能会被重置状态所攻击require(withdrawalRequested[withdrawal.user], "提取请求不再有效"); // 处理提取uint256 amount = withdrawal.amount; require(balances[withdrawal.user] >= amount, "余额不足"); // 更新余额balances[withdrawal.user] -= amount; // 重置提取请求withdrawalRequested[withdrawal.user] = false; // 发送资金(bool success, ) = payable(withdrawal.user).call{value:amount}(""); require(success, "资金发送失败"); // 移动到队列中的下一个currentIndex++; }

Para aproveitar isso, um invasor pode fazer o seguinte:

  1. Iniciar uma solicitação de busca.
  2. Chame a função resetUserStatus .
  3. A função processNextWithdrawal recairá, causando um ataque contínuo do DOS.

Remédios :

  • Limite as permissões para modificar withdrawalRequested ao administrador.
  • Verifique as verificações para evitar transações de valor zero.
  • Implemente uma função de fallback para lidar com erros inesperados.

Sol-Am-Dosa-5: Os baixos tokens decimais levarão ao DOS?

Problema : Tokens com baixos casas decimais podem causar problemas de divisão inteira, arredondando para zero .

Imagine um contrato de streaming de token alocando tokens por um período de tempo. Se tokensPerSecond rodadas zero devido à divisão inteira com baixos tokens decimais, a função de alocação será bloqueada. Pergunta da lista de verificação : "Os baixos tokens decimais levam ao DOS?" Solução : Implemente a lógica para lidar com baixos pontos decimais para evitar a interrupção dos processos de negociação devido a erros de arredondamento. Exemplo :

Considere um contrato TokenStream que transmite regularmente um certo número de tokens para os usuários, onde:

  1. total_tokens precisa ser transferido para o contrato
  2. token_per_second pode ser arredondado para zero porque estamos usando tokens com um ponto decimal de 1
  3. A função distributeTokens voltará
 contract TokenStream { IERC20 public token; uint256 public streamDuration; uint256 public tokensPerSecond; constructor(IERC20 _token, uint256 _streamDuration, uint256 _tokensPerSecond) { token = _token; streamDuration = _streamDuration; tokensPerSecond = _tokensPerSecond; } function distributeTokens(address recipient) external { uint256 balance = token.balanceOf(address(this)); uint256 amount = tokensPerSecond * streamDuration; uint256 tokensToSend = amount > balance ? balance : amount; require(tokensToSend > 0, "没有足够的代币进行流送"); token.transfer(recipient, tokensToSend); } } contract LowDecimalToken is ERC20 { constructor() ERC20("LowDecimalToken", "LDT") { _mint(msg.sender, 100000 * (10 ** decimals())); } function decimals() public view virtual override returns (uint8) { return 1; // 模拟小数点为低的代币} }

Nesse caso, o teste testDOSWithLowDecimalTokens no TokenStreamTest será revertido.

Solução : Certifique -se de que o contrato lida com os baixos tokens decimais corretamente, aliviando os problemas causados ​​pelo arredondamento dos números inteiros durante o processo de cálculo, dimensionando as fórmulas matemáticas .

SOL-AM-DOSA-6: O protocolo lida com segurança às interações de contrato externo?

Problema : Muitos contratos inteligentes dependem de contratos externos para interagir. O comportamento inesperado de contratos externos pode fazer com que todo o sistema recue . A falha em lidar com esses erros externos pode levar a vulnerabilidades do DOS.

Pergunta da lista de verificação : "O protocolo lida com as interações de contrato externo com segurança?"

Solução : Garanta um forte tratamento de erros para interações de contrato externas para proteger a integridade do protocolo, independentemente do desempenho de contratos externos.

Exemplo : considere um contrato que interage com uma fonte de dados de preços de cadeia externa. Se você não usar o Try/Catch para obter um manuseio de erro adequado, quaisquer reversão de fontes de dados externas se propagam para o superior e farão com que o contrato seja revertido.

  1. A função getPrice recupera dados de preço.
  2. Quando o Oracle do ChainLink externo falhar, todo o código será revertido.
  3. calculateSomethingImportant a função é importante depende do getPrice e também reverterá.
 contract PriceDependentContract { AggregatorV3Interface public priceFeed; constructor(address _priceFeed) { priceFeed = AggregatorV3Interface(_priceFeed); } // 易受攻击的函数,在没有处理可能的Chainlink 回滚的情况下获取价格function getPrice() public view returns (uint256) { (, int256 price, , , ) = priceFeed.latestRoundData(); // 易受攻击的行:没有错误处理require(price > 0, "价格必须为正"); return uint256(price); } function calculateSomethingImportant() public view returns (uint256) { uint256 price = getPrice(); // ... 使用价格的一些重要计算return price * 2; }

Solução : envolva chamadas de contrato externo em um bloco de tentativa/captura para lidar com erros de reversão e implementar valores de reversão ou cache.

Nota : Há um caso de borda em que o contrato externo consome intencionalmente gás , que também pode falhar no bloco de captura! Discutiremos isso mais tarde.

para concluir

Exploramos três verificações importantes projetadas para aprimorar a capacidade do seu contrato inteligente de resistir aos ataques do DOS: vulnerabilidades de manuseio de filas , desafios associados a baixos tokens decimais e a importância de lidar com as interações externas do contrato com segurança .

Lembre -se de que os exemplos fornecidos têm como objetivo ilustrar as vulnerabilidades principais. É muito importante entender os princípios básicos e adaptar esses conceitos aos seus casos de uso específicos.

Ao implementar essas sugestões, você pode melhorar significativamente a segurança e a resiliência de seus contratos inteligentes.

Fique atento para a próxima parte da série Solodit Checklist Resolution.

  • Link original: cyfrin.io/blog/solodit-c ...
  • A Comunidade Dengliana Assistente de IA traduz excelentes artigos em inglês para todos. Se houver alguma área em que a tradução não seja compreensível, por favor me perdoe ~

Últimas atualizações

Artigos Populares

Recomendações de jogos

Recomendação de software