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:
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.
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.
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ý:
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
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.
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.
16 thích
Phần thưởng
16
8
Chia sẻ
Bình luận
0/400
WhaleWatcher
· 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
CryptoSourGrape
· 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
PancakeFlippa
· 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
LazyDevMiner
· 07-17 19:29
Việc viết mã thì nói ở kiếp sau đi 8
Xem bản gốcTrả lời0
NftPhilanthropist
· 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
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:
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.
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.
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()); }
}
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) }
}
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.