Unchecked Deserialization
Detects unchecked deserialization of account data that may panic on malformed input.
Unchecked Deserialization
Overview
Remediation Guide: How to Fix Unchecked Deserialization
The unchecked deserialization detector identifies Solana programs that deserialize account data without proper error handling. When deserialization results are unwrapped, cast without validation, or used without discriminator checks, malformed account data can cause panics, denial of service, or processing of invalid state.
Sigvex tracks account data loads, subsequent cast/deserialization operations, and verifies whether error-handling branches protect the deserialized values before use.
Why This Is an Issue
- Program panics:
unwrap()orexpect()on malformed data crashes the program, wasting compute budget. - Denial of service: an attacker can repeatedly submit transactions with malformed accounts to crash the program.
- Invalid state processing: if deserialization fails silently (e.g., reading garbage bytes as valid data), the program may execute incorrect logic.
CWE mapping: CWE-690 (Unchecked Return Value), CWE-20 (Improper Input Validation).
How to Resolve
Native Solana
pub fn process(account: &AccountInfo) -> ProgramResult {
let data = account.data.borrow();
// Check data length
if data.len() < MyStruct::LEN {
return Err(ProgramError::InvalidAccountData);
}
// Check discriminator
if data[0..8] != MY_DISCRIMINATOR {
return Err(ProgramError::InvalidAccountData);
}
// Safe deserialization with error handling
let state = MyStruct::try_from_slice(&data[8..])
.map_err(|_| ProgramError::InvalidAccountData)?;
process_state(state)
}
Anchor
// Anchor validates discriminator and deserializes automatically
#[derive(Accounts)]
pub struct Process<'info> {
pub state: Account<'info, MyState>,
}
Examples
Vulnerable
let data = account.data.borrow();
let state = MyStruct::try_from_slice(&data).unwrap(); // Panics on malformed data!
Fixed
let data = account.data.borrow();
let state = MyStruct::try_from_slice(&data)
.map_err(|_| ProgramError::InvalidAccountData)?;
JSON Finding
{
"detector": "unchecked-deserialization",
"severity": "High",
"confidence": 0.75,
"title": "Unchecked Deserialization Result",
"description": "Deserialized account data is used without error handling.",
"cwe": [690]
}
Detection Methodology
The detector identifies account data variables, tracks deserialization-like operations (casts, complex expressions on account data), and checks whether error-handling branches protect the result before use. It also reports functions that process multiple account data fields without any conditional branches, suggesting absent validation.
Limitations
- Cast operations are used as a proxy for deserialization since exact Borsh calls are not distinguishable in decompiled bytecode.
- The detector may produce false positives for simple field extractions that do not require error handling.
- Programs with discriminator validation receive reduced confidence since type identity is already verified.
Related Detectors
- Unsafe Deserialization - detects variable-offset access without bounds checks.
- Zero Copy Deserialization - detects unsafe zero-copy patterns.