RustスマートコントラクトDoS攻撃防范実戦ガイド

Rustスマートコントラクト育成日記:サービス拒否攻撃防范

サービス拒否(DoS)攻撃は、スマートコントラクトが一定期間、または永続的に正常に使用できなくなる可能性があります。一般的な原因には次のものが含まれます:

  1. コントラクトロジックにおける計算の複雑さの問題が、Gas消費が制限を超える原因となる。

  2. クロスコントラクト呼び出しの際、外部コントラクトの実行状態に対する不適切な依存が本コントラクトをブロックする原因となります。

  3. コントラクト所有者のプライベートキーが失われ、特権関数が呼び出せず、重要なシステム状態が更新できません。

以下の具体的な例を通じて、DoS攻撃の脆弱性とその解決策を分析します。

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

以下はシンプルな"分配"スマートコントラクトで、DoSリスクがあります:

さび #[near_bindgen] #[derive(BorshDeserialize、BorshSerialize)] pub struct コントラクト { パブ登録:Vec、 パブアカウント: UnorderedMap<accountid, balance="">, }

impl コントラクト { 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
        );
    }
}

}

問題は、registered配列のサイズに制限がなく、悪意のあるユーザーによって大きくなりすぎる可能性があるため、distribute_token関数の実行時にGas消費が制限を超えてしまうことです。

提案された解決策:

  1. registered 配列のサイズを制限します。

  2. "出金"モードを採用し、ユーザーが自ら報酬を引き出すことを可能にし、契約が自動的に配布するのではなく。

!

2. コントラクト間の状態依存によるコントラクトのブロック

以下は"入札"スマートコントラクトの例です:

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

impl コントラクト { 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)
}

#[private]
pub fn account_resolve(&mut self, sender_id: AccountId, amount: u128) {
    一致 env::p romise_result(0) {
        PromiseResult::NotReady => 到達不能!()
        PromiseResult::Successful(_) => {
            ext_ft_token::ft_transfer(
                self.current_leader.clone()、
                self.highest_bid、
                &FTTOKENや
                0,
                GAS_FOR_SINGLE_CALL*2、
            );
            self.current_leader = sender_id;
            self.highest_bid = 金額;
        }
        PromiseResult::失敗 => {
            ext_ft_token::ft_transfer(
                sender_id.clone()、
                量
                &FTTOKENや
                0,
                GAS_FOR_SINGLE_CALL*2、
            );
            log!("今すぐ戻る");
        }
    };
}

}

問題は、契約の状態更新が外部契約の呼び出しに依存していることです。前の最高入札者のアカウントがキャンセルされている場合、後続の入札者は状態を更新できなくなります。

提案された解決策:

外部呼び出しが失敗する可能性を考慮し、合理的なエラーハンドリングメカニズムを実装します。例えば、返却できないトークンを契約内に一時保管し、後でユーザーが自主的に引き出すことを許可します。

3. 所有者のプライベートキーの喪失

多くの契約には所有者のみが実行できる特権関数があります。所有者の秘密鍵が失われると、これらの関数は呼び出せなくなり、契約が正常に機能しなくなる可能性があります。

提案された解決策:

1.複数の契約所有者を設定して、共同で管理します。

  1. 単一の所有者の制御に代わってマルチシグネチャメカニズムを採用する。

  2. 非中央集権的なスマートコントラクトガバナンスメカニズムを実現する。

これらの対策を通じて、スマートコントラクトにおけるサービス拒否攻撃のリスクを効果的に低減し、契約の安全性と信頼性を向上させることができます。

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

原文表示
このページには第三者のコンテンツが含まれている場合があり、情報提供のみを目的としております(表明・保証をするものではありません)。Gateによる見解の支持や、金融・専門的な助言とみなされるべきものではありません。詳細については免責事項をご覧ください。
  • 報酬
  • 8
  • 共有
コメント
0/400
MEVHunterWangvip
· 59分前
契約を台無しにするのは、手に取って掴むのと同じだ。
原文表示返信0
ProofOfNothingvip
· 4時間前
また形式主義の机上の空論です
原文表示返信0
LuckyHashValuevip
· 8時間前
攻撃を防げず、ゼロまで落ちるよ
原文表示返信0
ColdWalletGuardianvip
· 8時間前
ブロックチェーン入門標配知識点
原文表示返信0
SelfSovereignStevevip
· 8時間前
秘密鍵を失うと大変だ
原文表示返信0
StableBoivip
· 8時間前
この契約はリスクがかなり多いですね。安定性があまり良くないです。
原文表示返信0
Ser_This_Is_A_Casinovip
· 8時間前
あ~Rustは本当に難しい、Solidityを考えてみてはどうですか?
原文表示返信0
GasFeeThundervip
· 8時間前
ガスを食べ過ぎてどうする?遅かれ早かれ契約がすっからかんになる。
原文表示返信0
いつでもどこでも暗号資産取引
qrCode
スキャンしてGateアプリをダウンロード
コミュニティ
日本語
  • 简体中文
  • English
  • Tiếng Việt
  • 繁體中文
  • Español
  • Русский
  • Français (Afrique)
  • Português (Portugal)
  • Bahasa Indonesia
  • 日本語
  • بالعربية
  • Українська
  • Português (Brasil)