Skip to content

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

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.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions