Узнайте, как предотвратить атаки отказа в обслуживании (DOS) в интеллектуальных контрактах, обеспечивая безопасность очередей, обрабатывая низкие десятичные токены и надежно управляя внешними вызовами.
Добро пожаловать в серию разрешения контрольного списка Solodit . Мы продолжим изучать контрольные контрольные списки Solodit Smart Contract Audit , сосредоточившись на практических стратегиях написания безопасных и устойчивых интеллектуальных контрактов .
Этот контрольный список помогает вам определить потенциальные уязвимости и реализовать меры по проактивной безопасности. В предыдущем разделе « Резолюция контрольного списка Solodit (1) » мы изучили три контрольных списка ( схема извлечения, минимальная сумма транзакции и черный список ), связанные с атакой отказа в обслуживании (DOS), и предоставили решения для разработчиков. Если вы еще не читали его, я рекомендую проверить статью, прежде чем продолжить.
В этой статье мы обсудим три других элемента в контрольном списке, вновь сосредоточившись на атаках DOS. Мы погрузимся в уязвимости обработки очередей , проблемы, связанные с низкими десятичными токенами , и важность безопасной обработки внешних контрактных вызовов .
Для лучшего опыта откройте тег контрольного списка Solodit для справки.
Вот что мы обсудим сегодня:
Sol-AM-DOSA-4: Блокировка Обработка очередей : эта проблема возникает, когда злоумышленник манипулирует очередью, чтобы пауза или прерывать ее операции, что приводит к DOS. Мы рассмотрим, как злоумышленники могут уничтожить очереди на обработку.
Sol-Am-Dosa-5: низкие десятичные токены : проблемы, которые возникают при решении жетонов с низкими десятичными местами. Расчет, особенно разделение, может быть усечен до нуля, что приводит к неожиданному и вредному поведению. Эти токены с низким уровнем рецепта могут вызывать проблемы с целочисленным делением, тем самым мешая ключевым функциям.
Sol-AM-DOSA-6: Небезопасные внешние вызовы : мы рассмотрим, как полагаться на внешние контракты без надлежащей обработки ошибок для создания уязвимостей. Когда сбой внешнего вызова не обрабатывается правильно, это может привести к откату от всего контракта.
Атаки в реальном мире доказывают, что потенциальный ущерб может нанести эти уязвимости. Проект понесл огромные потери из -за, казалось бы, незначительной халатности.
Контрольные списки Solodit основаны на выводах аудита, уязвимых отчетах о наградах и событиях в реальном мире. Изучая эти контрольные списки, вы можете учиться на прошлых ошибках и повысить безопасность вашего кода .
Теперь давайте посмотрим на каждый чек -элемент один через один через пример кода. Эти примеры были упрощены, чтобы выделить основные уязвимости.
Проблема : если ваш умный контракт зависит от очереди для обработки задач, злоумышленник может манипулировать конкретным состоянием в очереди, чтобы предотвратить правильную обработку.
Вопрос контрольного списка : «Может ли злоумышленник блокировать или предотвратить обработку очередей, чтобы вызвать отключение обслуживания?»
Решение : ваш механизм обработки очередей требует мощной обработки ошибок и механизмов отступления , чтобы гарантировать, что проблемы могут продолжать обрабатывать, даже если они возникают.
Пример :
Рассмотрим пример извлечения очереди:
Пользователь запрашивает извлечение, и некоторые флаги указывают на то, что запрос активен.
Злоумышленник может использовать функцию resetUserStatus
после того, как извлечена, чтобы предотвратить ту же работу других пользователей.
// 易受攻击的函数:可以被利用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++; }
Чтобы воспользоваться этим, злоумышленник может сделать следующее:
resetUserStatus
.processNextWithdrawal
будет отказываться, вызывая непрерывную атаку DOS.Средства правовой защиты :
withdrawalRequested
администратору.Проблема : Токены с низким десятичным десятичным центром могут вызвать проблемы целочисленного деления, таким образом, округление до нуля .
Представьте себе контракт на потоковую передачу токена в течение определенного периода времени. Если из -за целочисленного деления с низким десятичным токеном будет заблокирована tokensPerSecond
раунды до нуля из -за целочисленного деления с низким десятичным токеном, функция распределения будет заблокирована. Контрольный список вопрос : «Ведут ли низкие десятичные токены к DOS?» Решение : реализуйте логику для обработки низких десятичных точек , чтобы предотвратить прерывание торговых процессов из -за ошибок округления. Пример :
Рассмотрим контракт TokenStream
, который регулярно транслирует определенное количество токенов для пользователей, где:
total_tokens
необходимо перевести в контрактtoken_per_second
может быть округлен до нуля, потому что мы используем токены с десятичной точкой 1distributeTokens
будет отказываться 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; // 模拟小数点为低的代币} }
В этом случае тест testDOSWithLowDecimalTokens
в TokenStreamTest
будет откат.
Средство правовой защиты : Убедитесь, что контракт правильно обрабатывает низкие десятичные токены, что облегчает проблемы, вызванные целыми округления во время процесса расчета путем масштабирования математических формул .
Проблема : Многие умные контракты полагаются на внешние контракты для взаимодействия. Неожиданное поведение внешних контрактов может привести к откату всей системы . Неспособность справиться с этими внешними ошибками может привести к уязвимости DOS.
Контрольный список : «Безопасно ли справляется ли протокол внешний контрактный взаимодействие?»
Решение : обеспечить сильную обработку ошибок для внешних контрактных взаимодействий для защиты целостности протокола независимо от выполнения внешних контрактов.
Пример : рассмотрим контракт, который взаимодействует с источником данных о цене внешней сети. Если вы не используете Try/Catch для обработки ошибок, любые откаты от внешних источников данных будут распространяться на превосходство и привести к откату контракта.
getPrice
получает данные о ценах.calculateSomethingImportant
Function зависит от getPrice
, а также откатится назад. 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; }
Помощь : Оберните внешние контрактные вызовы в блоке Try/Catch, чтобы обработать ошибки отката и реализацию значений отката или кэша.
Примечание . Существует крайний случай, когда внешний контракт преднамеренно потребляет газ , который также может потерпеть неудачу блок улова! Мы обсудим это позже.
Мы исследуем три ключевых проверки, предназначенных для повышения способности вашего умного контракта противостоять атакам DOS: уязвимости обработки очередей , проблемы, связанные с низкими десятичными токенами , и важность безопасной обработки внешних контрактных взаимодействий .
Помните, что приведенные примеры предназначены для иллюстрации основных уязвимостей. Очень важно понимать основные принципы и адаптировать эти концепции к вашим конкретным вариантам использования.
Реализуя эти предложения, вы можете значительно повысить безопасность и устойчивость ваших умных контрактов.
Оставайтесь с нами для следующей части серии контрольных списков Solodit.
- Оригинальная ссылка: cyfrin.io/blog/solodit-c ...
- Помощник по искусственному интеллекту Denglian Community переводит отличные английские статьи для всех. Если есть какие -либо области, где перевод не понятен, пожалуйста, простите меня ~