RustスマートコントラクトDoS脆弱性分析:ループ遍歴、クロスコントラクト依存と権限設計

robot
概要作成中

RustスマートコントラクトにおけるDoS攻撃の脆弱性分析

DoS (サービス拒否)攻撃は、スマートコントラクトが一定期間、または永続的に正常に使用できなくなる原因となります。主な理由は次のとおりです:

  1. コントラクトのロジックに欠陥が存在する。例えば、いくつかのpublic関数の実装が計算の複雑さを考慮しておらず、Gas消費が制限を超える。

  2. クロスコントラクト呼び出し時に外部コントラクトの実行状態への依存。外部コントラクトの実行が信頼できない場合、本コントラクトがブロックされる可能性があります。

  3. 人為的要因、例えば契約所有者が秘密鍵を失うことにより、重要なシステムの状態が適時に更新されない。

以下の具体例を通じてDoS攻撃の脆弱性を分析します。

1. 外部から変更できる大規模なデータ構造をループ処理

以下は登録ユーザーの「分紅」のための簡単なスマートコントラクトです:

さび #[near_bindgen] #[derive(BorshDeserialize、BorshSerialize)] pub struct コントラクト { パブ登録:Vec、 パブアカウント: 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()); } else { self.registered.push(env::p redecessor_account_id()); } log!("登録済みアカウント {}", env::p redecessor_account_id()); }

pub fn distribute_token(&mut self, amount: u128) { assert_eq!(env::p redecessor_account_id(), ディストリビューター, "ERR_NOT_ALLOWED");

for cur_account in self.registered.iter() {
    バランス= 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.clone()、
        量
        &FTTOKENや
        0,
        GAS_FOR_SINGLE_CALL
    );
}

}

この契約の状態データself.registeredのサイズは無制限であり、悪意のあるユーザーによって過大に操作される可能性があります。その結果、distribute_tokenの実行時にGas消費が制限を超えて失敗する可能性があります。

推奨する引き出しモード: 契約者が先に記帳し、ユーザーはwithdraw関数を通じて自分で報酬を取り戻します。契約は単一のユーザーの報酬額を維持する必要があります。

!

2. クロスコントラクト状態依存による契約ブロッキング

「ビッド」契約について考えてみましょう。

さび #[near_bindgen] #[derive(BorshDeserialize、BorshSerialize)] pub struct コントラクト { パブ登録:Vec、 pub bid_price: UnorderedMap<accountid,balance>, 公開current_leader: AccountId, パブhighest_bid:U128、 パブの払い戻し:ブール }

pub fn bid(&mut self, sender_id: AccountId, amount: u128) -> PromiseOrValue { アサート!(amount > self.highest_bid);

if self.current_leader == DEFAULT_ACCOUNT {
    self.current_leader = sender_id;
    self.highest_bid = 金額;
} else {
    ext_ft_token::account_exist(
        self.current_leader.clone()、
        &FTTOKENや
        0,
        env::p repaid_gas() - GAS_FOR_SINGLE_CALL * 4、
    ).then(ext_self::account_resolve(
        sender_id、
        量
        &env::current_account_id()、
        0,
        GAS_FOR_SINGLE_CALL*3、
     ));
}

ログ!(
    "current_leader: {} highest_bid: {}",
    self.current_leader、
    self.highest_bid
);

PromiseOrValue::Value(0)

}

この契約のロジックは、前の最高入札者のトークンを返却することに依存して、新しい最高入札を更新します。もし前者のアカウントが解約されている場合、新しい入札はブロックされます。

解決方法: 外部呼び出しが失敗する可能性を考慮し、エラーハンドリングを強化する。返却できないトークンを一時保管し、その後ユーザーが自分で引き出すことができる。

3. 所有者の秘密鍵を紛失した

一部のコントラクト関数は、重要なシステム変数を変更するために、オーナーのみが実行できるように設定されています。もしオーナーが機能を果たせなくなった場合(、例えば秘密鍵を紛失した場合)、これらの機能は使用できなくなり、コントラクトが停止する可能性があります。

ソリューション:

  • 複数のオーナーによる共同ガバナンスの設定
  • 単一のオーナー権限管理の代わりにマルチシグ方案を採用する
  • 分散型ガバナンス機構の実現

合理的権限設計とガバナンスメカニズムは、単一障害点のリスクを効果的に低減し、契約のロバスト性を向上させることができます。

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

原文表示
このページには第三者のコンテンツが含まれている場合があり、情報提供のみを目的としております(表明・保証をするものではありません)。Gateによる見解の支持や、金融・専門的な助言とみなされるべきものではありません。詳細については免責事項をご覧ください。
  • 報酬
  • 7
  • リポスト
  • 共有
コメント
0/400
MEVHunterLuckyvip
· 07-17 08:49
ループで呼び出すのは超危険です。以前に損失を出したことがあります。
原文表示返信0
BridgeNomadvip
· 07-15 16:21
先月BSCでこの正確な攻撃ベクターを見た... 開発者たちはいつ学ぶのだろう、ため息
原文表示返信0
BearMarketSurvivorvip
· 07-14 20:00
コードバトルのベテランが帰ってきた、戦闘損失はポジション管理のおかげで減少した
原文表示返信0
BearMarketSurvivorvip
· 07-14 19:57
秘密鍵を失ったらどうする?慌ててしまった。
原文表示返信0
FlatlineTradervip
· 07-14 19:56
契約設計がこんなに悪いのに公開するのか
原文表示返信0
MetaverseVagrantvip
· 07-14 19:54
このバグは危険度が少し高いです
原文表示返信0
HodlVeteranvip
· 07-14 19:34
一見して暗号資産ベテランの翻車後の血の涙の教訓...
原文表示返信0
いつでもどこでも暗号資産取引
qrCode
スキャンしてGateアプリをダウンロード
コミュニティ
日本語
  • 简体中文
  • English
  • Tiếng Việt
  • 繁體中文
  • Español
  • Русский
  • Français (Afrique)
  • Português (Portugal)
  • Bahasa Indonesia
  • 日本語
  • بالعربية
  • Українська
  • Português (Brasil)