Подробное объяснение трех основных уязвимостей DoS атак на смарт-контракты и стратегии их предотвращения

Глубокий анализ атак типа «отказ в обслуживании» в смарт-контрактах

атака типа «отказ в обслуживании»(DoS)может привести к временной или постоянной невозможности нормального использования смарт-контрактов. Основные причины включают:

  1. Логика контракта содержит дефекты. Например, некоторые открытые функции не учитывают вычислительную сложность, что может превысить лимит Gas и привести к сбою транзакции.

  2. В вызовах между смарт-контрактами выполнение контракта зависит от состояния внешнего контракта. Ненадежное выполнение внешнего контракта может заблокировать выполнение данного контракта, например, если средства пользователя заблокированы и не могут быть внесены или выведены.

  3. Человеческий фактор, такой как потеря частного ключа владельцем контракта, приводит к тому, что некоторые функции с привилегиями не могут быть вызваны, и важные состояния системы не могут быть обновлены.

Ниже приведен анализ уязвимости атаки типа «отказ в обслуживании» на конкретных примерах:

1. Обход крупных структур данных, которые могут быть изменены извне

Вот простой смарт-контракт для «распределения дивидендов» пользователям:

ржавчина #[near_bindgen] #[derive(BorshDeserialize, BorshSerialize)] pub struct Контракт { pub зарегистрированные: Vec\u003caccountid\u003e, аккаунты пабов: UnorderedMap<accountid, balance="">, }

pub fn register_account(&mut self) { если self.accounts.insert(&env::p redecessor_account_id(), &0).is_ some() { env::panic("Учетная запись уже зарегистрирована".to_string().as_bytes()); } иначе { self.registered.push(env::p redecessor_account_id()); } log!("Зарегистрированный аккаунт {}", env::predecessor_account_id()); }

pub fn distribute_token(&mut self, сумма: u128) { assert_eq!(env::p redecessor_account_id(), ДИСТРИБЬЮТОР, "ERR_NOT_ALLOWED");

для cur_account в self.registered.iter() {
    let balance = self.accounts.get(&cur_account).expect("ERR_GET");
    self.accounts.insert(&cur_account, &balance.checked_add(amount).expect("ERR_ADD" ));
    log!("Попробуйте распределить на счет {}", &cur_account);
    ext_ft_token::ft_transfer(
        cur_account.клон(),
        сумма,
        &FTTOKEN,
        0,
        GAS_FOR_SINGLE_CALL
    );
}

}

Данные состояния контракта self.registered имеют неограниченный размер и могут быть использованы злонамеренными пользователями. Когда зарегистрированных пользователей слишком много, выполнение distribute_token может превысить предел Gas, что приведет к неудаче транзакции.

Рекомендуется изменить режим вывода: не активно распределять дивиденды всем пользователям, а вести учет и установить функцию withdraw, позволяющую пользователям самостоятельно извлекать вознаграждения.

!

2. Зависимость состояния между смарт-контрактами приводит к блокировке

Рассмотрим сценарий с контрактом на аукцион:

ржавчина #[near_bindgen] #[derive(BorshDeserialize, BorshSerialize)] pub struct Contract { pub зарегистрированные: Vec\u003caccountid\u003e, паб bid_price: UnorderedMap<accountid,balance>, pub current_leader: AccountId, highest_bid паб: U128, Возврат средств в пабе: Bool }

pub fn bid(&mut self, sender_id: AccountId, amount: u128) -> PromiseOrValue { assert!(amount > self.highest_bid); если self.current_leader == DEFAULT_ACCOUNT { self.current_leader = sender_id; self.highest_bid = сумма; } иначе { ext_ft_token::account_exist( self.current_leader.клон(), &FTTOKEN, 0, env::предоплаченный_газ() - ГАЗ_ДЛЯ_ОДИНОЧНОГО_ВЫЗОВА * 4, ).then(ext_self::account_resolve( sender_id, сумма, &env::current_account_id(), 0, GAS_FOR_SINGLE_CALL*3, )); } бревно!( "текущий_лидер: {} наивысшая_ставка: {}", self.current_leader, self.highest_bid ); PromiseOrValue::Value(0) }

#[private] pub fn account_resolve(&mut self, sender_id: AccountId, amount: u128) { совпадение env::promise_result(0) { PromiseResult::NotReady => недостижимо!(), PromiseResult::Successful(_) => { ext_ft_token::ft_transfer( self.current_leader.клон(), self.highest_bid, &FTTOKEN, 0, GAS_FOR_SINGLE_CALL * 2, ); self.current_leader = sender_id; self.highest_bid = сумма; } PromiseResult::Failed => { ext_ft_token::ft_transfer( sender_id.клон(), сумма, &FTTOKEN, 0, GAS_FOR_SINGLE_CALL * 2, ); log!("Вернуться сейчас"); } }; }

Данный смарт-контракт требует возврата токенов предыдущего участника, чтобы обновить наивысшую ставку. Если предыдущий участник аннулирует учетную запись во внешнем контракте, это приведет к тому, что система не сможет обновить наивысшую ставку.

Рекомендуется добавить механизм обработки ошибок, например, поместить токены, которые невозможно вернуть, на счет lost_found смарт-контракта, а затем позволить пользователям извлекать их.

3. Потеря приватного ключа владельца

Некоторые функции контракта настроены так, что их может выполнять только владелец, для изменения ключевых системных переменных. Когда владелец не может выполнять свои обязанности (, например, в случае потери приватного ключа ), это может привести к блокировке средств или приостановке транзакций.

Рекомендуется использовать механизм многоподписей вместо единоличного контроля владельца для реализации децентрализованного управления.

Таким образом, при разработке смарт-контрактов необходимо充分 учитывать различные потенциальные риски атаки типа «отказ в обслуживании» и принимать соответствующие меры предосторожности для обеспечения долгосрочной стабильной работы контракта.

! </accountid,balance></accountid,>

Посмотреть Оригинал
На этой странице может содержаться сторонний контент, который предоставляется исключительно в информационных целях (не в качестве заявлений/гарантий) и не должен рассматриваться как поддержка взглядов компании Gate или как финансовый или профессиональный совет. Подробности смотрите в разделе «Отказ от ответственности» .
  • Награда
  • 6
  • Поделиться
комментарий
0/400
PrivacyMaximalistvip
· 10ч назад
Закрытый ключ потерян, всё пропало. Кто понимает?
Посмотреть ОригиналОтветить0
GmGnSleepervip
· 10ч назад
Снова это вина Gas fees.
Посмотреть ОригиналОтветить0
NFTHoardervip
· 10ч назад
Опять кто-то потерял Закрытый ключ?
Посмотреть ОригиналОтветить0
NFTArchaeologisvip
· 10ч назад
Уязвимости смарт-контрактов эпохи ранней Газовой войны действительно являются ценными цифровыми археологическими материалами.
Посмотреть ОригиналОтветить0
MemeCuratorvip
· 10ч назад
Снова чьи-то контракты были взломаны? Такие очевидные недостатки в контракте следовало бы избежать.
Посмотреть ОригиналОтветить0
CompoundPersonalityvip
· 10ч назад
Координаты в блокчейне ape лежащий игрок, скорее всего, занимается смарт-контрактами и безопасностью.
Посмотреть ОригиналОтветить0
  • Закрепить