Skip to main content
Sigvex

Borsh Length DoS

Detects unbounded Borsh Vec/String length prefix usage that can cause DoS.

Borsh Length DoS

Overview

The Borsh length DoS detector identifies when account data is deserialized using patterns that read a 4-byte u32 length prefix from untrusted account data and use it to control allocation size or loop iteration count without bounds validation. Attackers can craft malicious data with u32::MAX as the length prefix, causing allocations that exhaust compute units.

For remediation guidance, see Borsh Length DoS Remediation.

Why This Is an Issue

Borsh serialization uses a 4-byte little-endian u32 prefix for Vec and String lengths. When deserializing from untrusted account data, if the program reads this prefix and allocates a buffer of that size without validation, an attacker can set the prefix to u32::MAX (4,294,967,295), causing an enormous allocation attempt that exhausts the compute budget before any actual data processing occurs.

How to Resolve

Before (Vulnerable)

// Vulnerable: Borsh deserialization without length bounds
let data = account.data.borrow();
let items: Vec<Item> = BorshDeserialize::deserialize(&mut &data[..])?;
// If length prefix is u32::MAX, allocation exhausts compute

After (Fixed)

// Fixed: validate length before allocation
let data = account.data.borrow();
let len = u32::from_le_bytes(data[0..4].try_into().unwrap()) as usize;
require!(len <= MAX_ITEMS, ErrorCode::DataTooLarge);
let items: Vec<Item> = BorshDeserialize::deserialize(&mut &data[..])?;

Example JSON Finding

{
  "detector": "borsh-length-dos",
  "severity": "medium",
  "confidence": 0.65,
  "message": "4-byte length prefix read from account data used in allocation without bounds check",
  "location": { "function": "process", "block": 1, "statement": 3 }
}

Detection Methodology

  1. Length prefix identification: Detects 4-byte reads from account data at Vec/String field offsets.
  2. Allocation tracking: Traces length prefix variables into allocation-sized operations.
  3. Bounds check search: Verifies that length values are compared against upper bounds before use.

Limitations

False positives: Programs with account data sizes inherently bounded by rent-exempt requirements. False negatives: Custom deserialization that does not follow Borsh patterns.

References