Skip to content

audit F9 [security]: VoteThreshold::Count(0) permits any single admin to unilaterally pass governance proposals #609

@intendednull

Description

@intendednull

File: crates/state/src/server.rs:199
Severity: security
Obvious? no

meets_threshold evaluates Count(n) as yes_count >= (n as usize).min(admin_count); with n = 0 the right-hand side is 0, so the predicate is true for every non-negative yes_count. There is no n >= 1 validation anywhere on the path — apply_proposed_action::SetVoteThreshold blindly stores the threshold supplied in the payload (materialize.rs:240-242).

Bypass: the genesis owner (or any admin who can muster majority once) emits Propose { action: SetVoteThreshold { threshold: Count(0) } }. The proposer auto-yes records yes_count = 1, the owner_override or majority passes the threshold change, and from then on every Propose from any admin auto-applies on its sole proposer-yes vote. A hostile admin can now Propose { GrantAdmin { ... } } or Propose { KickMember { genesis_author } } and it lands with zero peer votes — turning a multi-admin server into a single-admin dictatorship via one threshold change.

Fix: clamp on the apply side: let n = n.max(1); state.vote_threshold = VoteThreshold::Count(n.min(state.admins.len() as u32)) (or reject the apply outright on n == 0). Also enforce the floor in meets_threshold for defense in depth: Count(n) => yes_count >= (n as usize).clamp(1, admin_count).


Filed by /general-audit @ 88498a5 (2026-05-04). master: #600.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions