Phân tích và giải pháp cho lỗ hổng tấn công DoS trong hợp đồng thông minh Rust

Tấn công từ chối dịch vụ trong hợp đồng thông minh Rust

tấn công từ chối dịch vụ ( DoS ) có thể dẫn đến hợp đồng thông minh không thể sử dụng bình thường trong một khoảng thời gian hoặc thậm chí vĩnh viễn. Nguyên nhân chính bao gồm:

  1. Logic hợp đồng có khuyết điểm, chẳng hạn như độ phức tạp tính toán của một số hàm quá cao, dẫn đến việc tiêu thụ Gas vượt quá giới hạn.

  2. Trong việc gọi hợp đồng chéo, việc thực thi hợp đồng phụ thuộc vào trạng thái của hợp đồng bên ngoài, có thể bị hợp đồng bên ngoài chặn.

  3. Yếu tố con người, như việc chủ hợp đồng mất khóa riêng, dẫn đến việc không thể gọi hàm đặc quyền.

Dưới đây là phân tích về lỗ hổng tấn công từ chối dịch vụ trong hợp đồng thông minh thông qua các ví dụ cụ thể.

1. Duyệt qua các cấu trúc dữ liệu lớn có thể bị sửa đổi từ bên ngoài

Dưới đây là một hợp đồng đơn giản để phân chia cổ tức cho người dùng đã đăng ký:

gỉ #[near_bindgen] #[derive(BorshDeserialize, BorshSerialize)] pub struct Contract { pub registered: Vec\u003caccountid\u003e, pub accounts: UnorderedMap\u003caccountid, balance=""\u003e, }

impl Hợp đồng { pub fn register_account(&mut self) { nếu self.accounts.insert(&env::predecessor_account_id(), &0).is_some() { env::panic("Tài khoản đã được đăng ký".to_string().as_bytes()); } else { self.registered.push(env::predecessor_account_id()); } log!("đăng ký tài khoản {}", env::predecessor_account_id()); }

pub fn distribute_token(&mut self, amount: u128) {
    assert_eq!(env::predecessor_account_id(), DISTRIBUTOR, "không có quyền thao tác");
    for account in self.registered.iter() {
        let balance = self.accounts.get(&account).expect("获取失败");
        self.accounts.insert(\u0026account, \u0026balance.checked_add(amount).expect("加法溢出")); 
        log!("cố gắng phân phát cho tài khoản {}", &tài khoản);
        ext_ft_token::ft_transfer(
            account.clone(),
            số lượng,
            &FTTOKEN,
            0,
            GAS_FOR_SINGLE_CALL
        );
    }
}

}

Vấn đề của hợp đồng này là kích thước của mảng registered không có giới hạn, có thể bị người dùng ác ý thao túng trở nên quá lớn, dẫn đến việc tiêu thụ Gas của hàm distribute_token quá cao.

Giải pháp được đề xuất:

Áp dụng chế độ rút tiền để tái cấu trúc hợp đồng. Để người dùng chủ động gọi hàm rút tiền để nhận thưởng, hợp đồng chỉ cần ghi lại số tiền thưởng có thể rút của người dùng.

2. Sự phụ thuộc trạng thái giữa các hợp đồng gây ra tắc nghẽn

Xem xét một hợp đồng đấu giá:

gỉ #[near_bindgen] #[derive(BorshDeserialize, BorshSerialize)] pub struct Hợp đồng { pub registered: Vec\u003caccountid\u003e, pub bid_price: UnorderedMap<accountid,balance>, pub current_leader: AccountId, pub highest_bid: u128, pub refund: bool }

impl Hợp đồng { PromiseOrValue { assert!(số lượng > self.highest_bid); nếu self.current_leader == DEFAULT_ACCOUNT { self.current_leader = sender_id; self.highest_bid = amount; } else { ext_ft_token::account_exist( self.current_leader.clone)(, &FTTOKEN, 0, env::prepaid_gas() - GAS_FOR_SINGLE_CALL * 4, (.then)ext_self::account_resolve) sender_id, số lượng, &env::current_account_id((, 0, GAS_FOR_SINGLE_CALL * 3, (); } log!) "Người đặt giá cao nhất hiện tại: {} Giá đặt cao nhất: {}", self.current_leader, self.highest_bid ); PromiseOrValue::Value(0) }

#(
pub fn account_resolve)&mut self, sender_id: AccountId, amount: u128[private] {
    match env::promise_result(0) {
        PromiseResult::NotReady => unreachable!(),
        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 = amount;
        }
        PromiseResult::Failed => {
            ext_ft_token::ft_transfer)
                sender_id.clone)(,
                số lượng,
                &FTTOKEN,
                0,
                GAS_FOR_SINGLE_CALL * 2,
            (;
            log!)"Hoàn lại giá thầu hiện tại");
        }
    };
}

}

Vấn đề của hợp đồng này là: phải hoàn trả thành công token của người đặt giá trước đó để có thể cập nhật giá thầu cao nhất. Nếu người đặt giá trước đó hủy tài khoản, hợp đồng sẽ không thể thực hiện hoàn tiền và bị chặn lại.

Giải pháp:

Xem xét khả năng gọi hợp đồng bên ngoài có thể thất bại, thực hiện xử lý lỗi hợp lý. Có thể tạm giữ các token không thể hoàn trả trong hợp đồng, cho phép người dùng chủ động rút sau.

3. Mất khóa riêng của chủ hợp đồng

Một số hàm hợp đồng được thiết lập chỉ có chủ sở hữu mới có thể thực hiện, dùng để thay đổi các biến hệ thống quan trọng. Nếu khóa riêng của chủ sở hữu bị mất, các hàm này sẽ không thể được gọi, có thể dẫn đến việc hợp đồng không hoạt động bình thường.

Giải pháp:

Thiết lập nhiều chủ hợp đồng để cùng quản lý, hoặc áp dụng cơ chế đa chữ ký để thay thế quyền kiểm soát của một chủ sở hữu duy nhất, nhằm thực hiện quản trị phi tập trung.

\u003c/u128\u003e\u003c/accountid,balance\u003e\u003c/accountid\u003e\u003c/accountid,\u003e\u003c/accountid\u003e

Xem bản gốc
Trang này có thể chứa nội dung của bên thứ ba, được cung cấp chỉ nhằm mục đích thông tin (không phải là tuyên bố/bảo đảm) và không được coi là sự chứng thực cho quan điểm của Gate hoặc là lời khuyên về tài chính hoặc chuyên môn. Xem Tuyên bố từ chối trách nhiệm để biết chi tiết.
  • Phần thưởng
  • 8
  • Chia sẻ
Bình luận
0/400
WhaleWatchervip
· 07-20 17:14
Hợp đồng chỉ bị tấn công khi là cái rây.
Xem bản gốcTrả lời0
CryptoSourGrapevip
· 07-20 17:08
Nếu tôi biết lỗ hổng này sớm hơn, thì đâu cần rơi vào tình cảnh bây giờ ngày nào cũng phải bán khổ.
Xem bản gốcTrả lời0
PancakeFlippavip
· 07-18 18:19
Hợp đồng cũng có yêu cầu tối thiểu, ai bảo bạn kỹ thuật kém.
Xem bản gốcTrả lời0
LazyDevMinervip
· 07-17 19:29
Việc viết mã thì nói ở kiếp sau đi 8
Xem bản gốcTrả lời0
NftPhilanthropistvip
· 07-17 19:28
thực ra... *uống trà* một hợp đồng không hiệu quả về gas khác có thể được tối ưu hóa cho tác động xã hội. khi nào các nhà phát triển mới học về các phương pháp lập trình có ý thức vậy nhỉ smh
Xem bản gốcTrả lời0
just_another_walletvip
· 07-17 19:20
Các vấn đề an toàn phải được các anh em chú ý.
Xem bản gốcTrả lời0
NFTragedyvip
· 07-17 19:16
Vấn đề này, mã vẫn chưa hoàn thành...
Xem bản gốcTrả lời0
HalfBuddhaMoneyvip
· 07-17 19:01
Tôi chao, lại phải lấp hố, hợp đồng rác.
Xem bản gốcTrả lời0
Giao dịch tiền điện tử mọi lúc mọi nơi
qrCode
Quét để tải xuống ứng dụng Gate
Cộng đồng
Tiếng Việt
  • 简体中文
  • English
  • Tiếng Việt
  • 繁體中文
  • Español
  • Русский
  • Français (Afrique)
  • Português (Portugal)
  • Bahasa Indonesia
  • 日本語
  • بالعربية
  • Українська
  • Português (Brasil)