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) sẽ làm cho 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 về độ phức tạp tính toán, dẫn đến việc tiêu thụ Gas vượt quá giới hạn.
Khi gọi hợp đồng chéo, việc thực thi hợp đồng phụ thuộc vào hợp đồng bên ngoài không đáng tin cậy, dẫn đến tắc nghẽn.
Chủ sở hữu hợp đồng mất khóa riêng, không thể thực hiện chức năng đặc quyền để cập nhật trạng thái quan trọng.
Dưới đây là phân tích lỗ hổng tấn công từ chối dịch vụ (DoS) thông qua các ví dụ cụ thể.
1. Duyệt qua cấu trúc dữ liệu lớn có thể điều khiển từ bên ngoài
Dưới đây là một hợp đồng đơn giản để "chia lợi nhuận" cho người dùng:
gỉ
#[near_bindgen]
#[derive(BorshDeserialize, BorshSerialize)]
pub struct Hợp đồng {
pub registered: Vec\u003caccountid\u003e,
pub accounts: UnorderedMap\u003caccountid, balance=""\u003e,
}
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!("Tài khoản đã đăng ký {}", env::predecessor_account_id());
}
pub fn distribute_token(&mut self, amount: u128) {
assert_eq!(env::predecessor_account_id(), DISTRIBUTOR, "ERR_NOT_ALLOWED");
cho cur_account trong self.registered.iter() {
let balance = self.accounts.get(&cur_account).expect("ERR_GET");
self.accounts.insert(\u0026cur_account, \u0026balance.checked_add(amount).expect("ERR_ADD"));
log!("Cố gắng phân phối đến tài khoản {}", &cur_account);
ext_ft_token::ft_transfer(
cur_account.clone(),
số lượng,
&FTTOKEN,
0,
GAS_FOR_SINGLE_CALL
);
}
}
Ở đây kích thước self.registered không bị giới hạn, có thể bị người dùng độc hại thao túng trở nên quá lớn, dẫn đến chi phí Gas vượt quá giới hạn khi thực thi distribute_token.
Giải pháp: Không khuyến nghị duyệt qua các cấu trúc dữ liệu lớn có thể kiểm soát từ bên ngoài. Có thể áp dụng chế độ rút tiền, cho phép người dùng tự lấy lại "phần thưởng".
2. Sự phụ thuộc trạng thái giữa các hợp đồng gây ra tắc nghẽn
Việc trả lại token cho người đấu giá cao nhất trước đó là điều kiện tiên quyết để cập nhật trạng thái. Nếu tài khoản người dùng đó đã bị hủy, sẽ dẫn đến việc toàn bộ quá trình đấu giá bị chặn.
Giải pháp: Xem xét khả năng các cuộc gọi bên ngoài có thể thất bại, tăng cường xử lý lỗi. Có thể tạm giữ các token không thể hoàn lại, sau đó cho phép người dùng tự rút.
3. Mất khóa riêng của chủ sở hữu
Một số chức năng quan trọng chỉ được phép thực hiện bởi chủ sở hữu. Khi chủ sở hữu không thể thực hiện nhiệm vụ, ( như mất khóa riêng, ) sẽ dẫn đến hợp đồng không thể hoạt động bình thường.
Giải pháp: Thiết lập nhiều chủ sở hữu để cùng quản lý, hoặc áp dụng yêu cầu đa chữ ký thay thế cho việc 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.
7 thích
Phần thưởng
7
7
Chia sẻ
Bình luận
0/400
gaslight_gasfeez
· 11giờ trước
Cả bầy kiến đã tụ tập lại để chia sẻ phí gas.
Xem bản gốcTrả lời0
ImpermanentTherapist
· 11giờ trước
Lại đang làm những trò nhỏ với hợp đồng bên ngoài.
Xem bản gốcTrả lời0
WealthCoffee
· 11giờ trước
Lại là chuyện phí Gas, thật phiền phức.
Xem bản gốcTrả lời0
LiquidationTherapist
· 11giờ trước
Khóa hợp đồng thôi, đơn giản vậy đó.
Xem bản gốcTrả lời0
SquidTeacher
· 11giờ trước
Có lỗi cơ bản như mất khóa riêng sao?
Xem bản gốcTrả lời0
BlockTalk
· 11giờ trước
Khóa riêng bị mất thật sự rất đáng sợ
Xem bản gốcTrả lời0
CryptoAdventurer
· 11giờ trước
Lại thấy hợp đồng thông minh bị phá hủy, địa chỉ ví tiền một trận hỏa hoạn anh em ơi
Phân tích tấn công DoS vào hợp đồng thông minh: Giải thích trường hợp và chiến lược phòng thủ
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) sẽ làm cho 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 về độ phức tạp tính toán, dẫn đến việc tiêu thụ Gas vượt quá giới hạn.
Khi gọi hợp đồng chéo, việc thực thi hợp đồng phụ thuộc vào hợp đồng bên ngoài không đáng tin cậy, dẫn đến tắc nghẽn.
Chủ sở hữu hợp đồng mất khóa riêng, không thể thực hiện chức năng đặc quyền để cập nhật trạng thái quan trọng.
Dưới đây là phân tích lỗ hổng tấn công từ chối dịch vụ (DoS) thông qua các ví dụ cụ thể.
1. Duyệt qua cấu trúc dữ liệu lớn có thể điều khiển từ bên ngoài
Dưới đây là một hợp đồng đơn giản để "chia lợi nhuận" cho người dùng:
gỉ #[near_bindgen] #[derive(BorshDeserialize, BorshSerialize)] pub struct Hợp đồng { pub registered: Vec\u003caccountid\u003e, pub accounts: UnorderedMap\u003caccountid, balance=""\u003e, }
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!("Tài khoản đã đăng ký {}", env::predecessor_account_id()); }
pub fn distribute_token(&mut self, amount: u128) { assert_eq!(env::predecessor_account_id(), DISTRIBUTOR, "ERR_NOT_ALLOWED"); cho cur_account trong self.registered.iter() { let balance = self.accounts.get(&cur_account).expect("ERR_GET"); self.accounts.insert(\u0026cur_account, \u0026balance.checked_add(amount).expect("ERR_ADD")); log!("Cố gắng phân phối đến tài khoản {}", &cur_account); ext_ft_token::ft_transfer( cur_account.clone(), số lượng, &FTTOKEN, 0, GAS_FOR_SINGLE_CALL ); } }
Ở đây kích thước self.registered không bị giới hạn, có thể bị người dùng độc hại thao túng trở nên quá lớn, dẫn đến chi phí Gas vượt quá giới hạn khi thực thi distribute_token.
Giải pháp: Không khuyến nghị duyệt qua các cấu trúc dữ liệu lớn có thể kiểm soát từ bên ngoài. Có thể áp dụng chế độ rút tiền, cho phép người dùng tự lấy lại "phần thưởng".
2. Sự phụ thuộc trạng thái giữa các hợp đồng gây ra tắc nghẽn
Cân nhắc một hợp đồng "đấu giá":
gỉ #[near_bindgen] #[derive(BorshDeserialize, BorshSerialize)] pub struct Contract { pub registered: Vec\u003caccountid\u003e, pub bid_price: UnorderedMap\u003caccountid,balance\u003e, pub current_leader: AccountId, pub highest_bid: u128, pub hoàn tiền: bool }
PromiseOrValue { assert!(amount > 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!) "current_leader: {} highest_bid: {}", self.current_leader, self.highest_bid ); PromiseOrValue::Value(0) }
Việc trả lại token cho người đấu giá cao nhất trước đó là điều kiện tiên quyết để cập nhật trạng thái. Nếu tài khoản người dùng đó đã bị hủy, sẽ dẫn đến việc toàn bộ quá trình đấu giá bị chặn.
Giải pháp: Xem xét khả năng các cuộc gọi bên ngoài có thể thất bại, tăng cường xử lý lỗi. Có thể tạm giữ các token không thể hoàn lại, sau đó cho phép người dùng tự rút.
3. Mất khóa riêng của chủ sở hữu
Một số chức năng quan trọng chỉ được phép thực hiện bởi chủ sở hữu. Khi chủ sở hữu không thể thực hiện nhiệm vụ, ( như mất khóa riêng, ) sẽ dẫn đến hợp đồng không thể hoạt động bình thường.
Giải pháp: Thiết lập nhiều chủ sở hữu để cùng quản lý, hoặc áp dụng yêu cầu đa chữ ký thay thế cho việc 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.