Skip to content

Harden /gov/vote when the masternode cache is stale or empty #29

@bigpoppa-sys

Description

@bigpoppa-sys

Defensive audit finding.

POST /gov/vote currently fails open when the masternode snapshot is stale or empty. In routes/gov.js, stale snapshots produce an empty knownOutpoints set, and entries are rejected only when that set has entries and does not contain the submitted outpoint:

  • routes/gov.js:23-39 computes fresh from masternodesUpdatedAt.
  • routes/gov.js:200-207 sets knownOutpoints to new Set() when the snapshot is stale.
  • routes/gov.js:211-219 only rejects unknown outpoints when knownOutpoints.size > 0.

Production wiring in server.js:343-346 passes { masternodes: dataStore.masternodesArr, updatedAt: dataStore.masternodesUpdatedAt }. On cold boot masternodesUpdatedAt starts at 0, and services/masternodeTracker.js:37-77 only stamps it after a successful interval refresh. If the tracker has not completed its first refresh, or RPC/list refresh is down long enough to exceed the 30s freshness window, /gov/vote bypasses the current-masternode membership guard and relays any structurally valid, signed entry to Core. The existing test tests/gov.routes.test.js:373-389 explicitly locks in this fail-open behavior.

Impact:

This does not expose WIFs and still requires Core-valid vote signatures. However, during tracker outages an authenticated account can use the backend as a generic voteraw relay instead of being constrained to the backend's current live masternode view. That weakens defense-in-depth for last-minute voting workflows, compromised/pre-collected signatures, and RPC resource protection.

Suggested hardening:

  • Fail closed when the masternode snapshot is stale, e.g. return 503 { error: "masternode_cache_stale" } before relay.
  • Treat a fresh-but-empty knownOutpoints set as suspicious on mainnet and fail closed unless explicitly configured otherwise for tests/dev.
  • Consider kicking an immediate tracker refresh on boot instead of waiting for the first interval tick.
  • Update the test currently named fails open to voteraw when the masternode cache snapshot is stale to assert the safer behavior.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions