Phat Contract Runtime - XDZIBECX's results

Coprocessor for blockchains

General Information

Platform: Code4rena

Start Date: 01/03/2024

Pot Size: $60,500 USDC

Total HM: 4

Participants: 18

Period: 21 days

Judge: Lambda

Total Solo HM: 3

Id: 344

League: POLKADOT

Phala Network

Findings Distribution

Researcher Performance

Rank: 11/18

Findings: 1

Award: $69.85

🌟 Selected for report: 0

πŸš€ Solo Findings: 0

Findings Information

🌟 Selected for report: Cryptor

Also found by: 0xTheC0der, Bauchibred, Daniel526, XDZIBECX, ihtishamsudo, zhaojie

Labels

bug
disagree with severity
downgraded by judge
grade-b
insufficient quality report
QA (Quality Assurance)
sponsor confirmed
Q-01

Awards

69.8535 USDC - $69.85

External Links

Lines of code

https://github.com/code-423n4/2024-03-phala-network/blob/a01ffbe992560d8d0f17deadfb9b9a2bed38377e/phala-blockchain/crates/pink/runtime/src/runtime/pallet_pink.rs#L134-L146

Vulnerability details

Vulnerability details

The put_sidevm_code function within the specified pallet allows for the storage of wasm bytecode associated with a given owner account. and this function computes a fee based on the size of the bytecode plus a static item deposit fee. However, there is no explicit check or limit on the maximum size of the bytecode vector (Vec<u8>) that can be stored. Consequently, this oversight facilitates a potential attack vector where a malicious user could upload excessively large wasm binaries, leading to unchecked resource consumption. Such actions could significantly degrade blockchain performance due to storage exhaustion, increase operational costs for node operators, and potentially lead to a denial-of-service condition.

pub fn put_sidevm_code(
    owner: T::AccountId,
    code: Vec<u8>,
) -> Result<T::Hash, DispatchError> {
    let hash = T::Hashing::hash(&code);
    let bytes = code.len() + hash.as_ref().len();
    let fee = Self::deposit_per_byte()
        .saturating_mul(BalanceOf::<T>::saturated_from(bytes))
        .saturating_add(Self::deposit_per_item());
    Self::pay(&owner, fee)?;
    <SidevmCodes<T>>::insert(hash, WasmCode { owner, code });
    Ok(hash)
}

Impact

A malicious actor could exploit this vulnerability by repeatedly uploading very large wasm binaries to the blockchain. Since there's no explicit limit on the code size that can be stored, these actions could lead to significant storage consumption on nodes participating in the blockchain network.

Proof of Concept

class MockBlockchain: def __init__(self): self.storage = {} self.fee_schedule = {'deposit_per_byte': 1, 'deposit_per_item': 100} self.total_fees_collected = 0 def put_sidevm_code(self, owner, code): """ Simulates storing wasm code in the blockchain storage. """ code_size = len(code) fee = self.calculate_fee(code_size) # Simulate fee payment (here, simply adding to a total) self.total_fees_collected += fee # Store the code if fee payment is successful self.storage[owner] = code print(f"Stored code of size {code_size} bytes for owner '{owner}' with fee {fee}") def calculate_fee(self, code_size): """ Calculates the fee based on the size of the code. """ return self.fee_schedule['deposit_per_byte'] * code_size + self.fee_schedule['deposit_per_item'] # Create a mock blockchain instance mock_blockchain = MockBlockchain() # Define a list of code sizes to test, illustrating the lack of a size check code_sizes = [10, 100, 1000, 10000, 100000, 1000000, 10000000] for size in code_sizes: # Generate dummy code of specified size dummy_code = b'a' * size mock_blockchain.put_sidevm_code("Alice", dummy_code) print(f"Total fees collected: {mock_blockchain.total_fees_collected}")

as result : the Codes of varying sizes, ranging from 10 bytes to 10,000,000 bytes, were stored successfully for a single owner, 'Alice'. With each increase in code size, the fee calculated and collected also increased proportionally, based on the simplistic fee calculation model (1 unit per byte of code plus a flat fee of 100 units). The test concluded with a total of 11,111,810 units collected in fees, reflecting the cumulative cost of storing all the provided codes.

Tools Used

manual review

need a checks on the size of the wasm bytecode being uploaded through the put_sidevm_code function. Establish a maximum allowable size for wasm binaries that balances the need for legitimate functionality with the prevention of abuse

Assessed type

Other

#0 - c4-pre-sort

2024-03-25T07:55:29Z

141345 marked the issue as insufficient quality report

#1 - 141345

2024-03-25T07:55:34Z

wasm bytecode size invalid, the attacker pays the fee

#2 - c4-sponsor

2024-03-26T01:09:31Z

kvinwang (sponsor) acknowledged

#3 - kvinwang

2024-03-26T07:30:57Z

wasm bytecode size invalid, the attacker pays the fee

Correct. And there is a size limit check on-chain. But an additional check in the pink-runtime is a nice to have feature. Better as a QA level.

#4 - c4-sponsor

2024-03-26T07:31:03Z

kvinwang (sponsor) confirmed

#5 - c4-sponsor

2024-03-26T07:54:56Z

kvinwang marked the issue as disagree with severity

#6 - c4-judge

2024-03-27T13:44:01Z

OpenCoreCH changed the severity to QA (Quality Assurance)

#7 - c4-judge

2024-03-27T18:22:40Z

OpenCoreCH marked the issue as grade-b

AuditHub

A portfolio for auditors, a security profile for protocols, a hub for web3 security.

Built bymalatrax Β© 2024

Auditors

Browse

Contests

Browse

Get in touch

ContactTwitter