Anchor Constraint Ordering
Detects when Anchor account constraints are checked in incorrect order.
Anchor Constraint Ordering
Overview
The Anchor constraint ordering detector identifies Anchor programs where account constraints are validated in an unsafe order. The correct order is: discriminator (type), owner, signer, writable, then custom constraints. Checking constraints out of order can lead to TOCTOU attacks, type confusion, privilege escalation, and authorization bypass.
For remediation guidance, see Anchor Constraint Ordering Remediation.
Why This Is an Issue
When a signer check runs before an owner check, an attacker can pass any signer account — including one owned by a different program — and pass the signer validation. The owner check that follows may still pass if the account data coincidentally matches. Discriminator validation must come first because all subsequent checks assume the account is the correct type.
How to Resolve
Before (Vulnerable)
// Vulnerable: signer check before owner check
pub fn update(ctx: Context<Update>) -> Result<()> {
require!(ctx.accounts.user.is_signer, Unauthorized); // Checked first
require!(ctx.accounts.user.owner == &my_program::ID, InvalidOwner); // Too late
// ...
Ok(())
}
After (Fixed)
// Fixed: correct constraint order via Anchor attributes
#[derive(Accounts)]
pub struct Update<'info> {
#[account(
mut,
owner = my_program::ID, // Owner checked first by Anchor
)]
pub data_account: Account<'info, MyData>, // Discriminator auto-checked
pub user: Signer<'info>, // Signer checked by Anchor
}
Example JSON Finding
{
"detector": "anchor-constraint-ordering",
"severity": "medium",
"confidence": 0.6,
"message": "Signer constraint checked before owner constraint -- potential authorization bypass",
"location": { "function": "update", "block": 0, "statement": 1 }
}
Detection Methodology
- Constraint extraction: Identifies validation checks (discriminator, owner, signer, writable) in instruction handlers.
- Order analysis: Verifies constraints are checked in the correct sequence: discriminator, owner, signer, writable, custom.
- Cross-check gap detection: Flags missing intermediate constraints in the sequence.
Limitations
False positives: Programs using Anchor’s derive macro for account validation handle ordering automatically, but the bytecode may check them in a different order than source. False negatives: The HIR does not yet expose explicit constraint check operations, limiting full coverage.
Related Detectors
- Anchor Constraint Bypass — missing constraints entirely
- Anchor Constraint TOCTOU — time-of-check race conditions