Análise de vulnerabilidades DoS em contratos inteligentes Rust: iteração em loop, dependências entre contratos e design de permissões

robot
Geração do resumo em andamento

Análise de vulnerabilidades de ataque DoS em contratos inteligentes Rust

O ataque DoS (Denial of Service) pode fazer com que contratos inteligentes não possam ser utilizados normalmente por um período de tempo ou até permanentemente. As principais razões incluem:

  1. Existem falhas na lógica do contrato. Por exemplo, algumas implementações de funções públicas não consideram a complexidade computacional, resultando em consumo de Gas que ultrapassa o limite.

  2. Dependência do estado de execução de contratos externos ao chamar contratos cruzados. A execução de contratos externos pode ser não confiável e levar ao bloqueio deste contrato.

  3. Fatores humanos, como a perda da chave privada pelo proprietário do contrato, levam à incapacidade de atualizar atempadamente o estado importante do sistema.

A seguir, analisaremos a vulnerabilidade de ataque DoS através de exemplos concretos.

1. Percorrendo estruturas de dados grandes que podem ser alteradas externamente

A seguir está um contrato simples para "dividendos" para usuários registrados:

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

pub fn register_account(&mut self) { se self.accounts.insert(&env::predecessor_account_id(), &0).is_some() { env::panic("A conta já está registrada".to_string().as_bytes()); } else { self.registered.push(env::predecessor_account_id()); } log!("Conta registrada {}", env::predecessor_account_id()); }

pub fn distribute_token(&mut self, amount: u128) { assert_eq!(env::predecessor_account_id(), DISTRIBUIDOR, "ERR_NOT_ALLOWED");

para cur_account em self.registered.iter() {
    let balance = self.accounts.get(&cur_account).expect("ERR_GET");
    self.accounts.insert(&cur_account, &balance.checked_add(amount).expect("ERR_ADD"));
    log!("Tentar distribuir para a conta {}", &cur_account);
    
    ext_ft_token::ft_transfer(
        cur_account.clone(),
        montante,
        &FTTOKEN,
        0,
        GAS_FOR_SINGLE_CALL
    );
}

}

Os dados de estado do contrato self.registered têm tamanho ilimitado, podendo ser manipulados por usuários mal-intencionados para se tornarem excessivamente grandes. Isso leva a que a execução do distribute_token exceda o limite de consumo de Gas e falhe.

Recomenda-se mudar para o modo de retirada: a parte contratante primeiro faz a contabilidade, o usuário recupera a recompensa por meio da função withdraw. O contrato apenas precisa manter o montante de recompensa de um único usuário.

2. A dependência de estado entre contratos causa o bloqueio de contratos

Considere um contrato de "licitação":

ferrugem #[near_bindgen] #[derive(BorshDeserialize, BorshSerialize)] pub struct Contract { pub registered: Vec, pub bid_price: UnorderedMap\u003caccountid,balance\u003e, pub current_leader: AccountId, pub highest_bid: u128, pub refund: bool }

PromiseOrValue { assert!(amount > self.highest_bid);

se 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,
        montante,
        &env::current_account_id((,
        0,
        GAS_FOR_SINGLE_CALL * 3,
     ();
}

log!)
    "líder_atual: {} maior_lance: {}", 
    self.current_leader,
    self.highest_bid
);

PromiseOrValue::Value(0)

}

A lógica deste contrato depende do retorno do token do licitante anterior para atualizar a nova oferta mais alta. Se a conta do anterior estiver encerrada, a nova oferta será bloqueada.

Solução: considerar a possibilidade de falhas em chamadas externas e aumentar o tratamento de erros. Os tokens que não podem ser devolvidos podem ser armazenados temporariamente, para que o usuário os retire posteriormente.

3. Perda da chave privada do proprietário

Algumas funções de contrato são definidas para serem executadas apenas pelo owner, para alterar variáveis essenciais do sistema. Se o owner não puder desempenhar suas funções (, como a perda da chave privada ), essas funcionalidades não estarão disponíveis, o que pode levar à paralisação do contrato.

Solução:

  • Definir vários proprietários para governança conjunta
  • Adotar um esquema de múltiplas assinaturas em vez de controle de permissões de um único proprietário
  • Implementar um mecanismo de governança descentralizado

Um design de permissões razoável e um mecanismo de governança podem reduzir efetivamente o risco de falhas de ponto único e aumentar a robustez dos contratos.

</accountid,balance></accountid,>

Ver original
Esta página pode conter conteúdo de terceiros, que é fornecido apenas para fins informativos (não para representações/garantias) e não deve ser considerada como um endosso de suas opiniões pela Gate nem como aconselhamento financeiro ou profissional. Consulte a Isenção de responsabilidade para obter detalhes.
  • Recompensa
  • 7
  • Compartilhar
Comentário
0/400
MEVHunterLuckyvip
· 07-17 08:49
Percorrer em loop pode ser super perigoso. Já perdi antes.
Ver originalResponder0
BridgeNomadvip
· 07-15 16:21
vi este vetor de ataque exato na bsc no mês passado... quando é que os desenvolvedores vão aprender smh
Ver originalResponder0
BearMarketSurvivorvip
· 07-14 20:00
Código de veterano de campo de batalha retorna, as perdas de batalha devem ser compensadas com a gestão de posição.
Ver originalResponder0
BearMarketSurvivorvip
· 07-14 19:57
O que fazer se a chave privada se perder? Estou em pânico.
Ver originalResponder0
FlatlineTradervip
· 07-14 19:56
O design do contrato é tão ruim que foi lançado.
Ver originalResponder0
MetaverseVagrantvip
· 07-14 19:54
Este BUG tem um nível de perigo um pouco elevado.
Ver originalResponder0
HodlVeteranvip
· 07-14 19:34
Uma lição amarga e dolorosa após uma derrota evidente dos Veteranos da Criptografia...
Ver originalResponder0
  • Marcar
Faça trade de criptomoedas em qualquer lugar e a qualquer hora
qrCode
Escaneie o código para baixar o app da Gate
Comunidade
Português (Brasil)
  • 简体中文
  • English
  • Tiếng Việt
  • 繁體中文
  • Español
  • Русский
  • Français (Afrique)
  • Português (Portugal)
  • Bahasa Indonesia
  • 日本語
  • بالعربية
  • Українська
  • Português (Brasil)