Skip to content

Harden email-link (uid hashid) access in the member order flow #340

Description

@kylefritz

Priority: low — hardening, not an active incident. Found during the 2026-06-11 operational-flow audit (F3).

The member-facing flow (OrdersController, CreditItemsController, EmailPreferencesController, MenusController via UserHashidable) authenticates by a ?uid= hashid that identifies the user and skips authenticate_user!. These links are emailed to members. The security of every per-user action therefore rests on the hashid being unguessable, which depends on HASHID_SALT.

Hardening steps:

  • Confirm HASHID_SALT is set to a strong, random secret on Heroku (and is not committed). If unset, hashids fall back to a predictable default.
  • Enable config.sign_hashids in config/initializers/hashid.rb.
  • Longer term: treat email-link access as a scoped, expiring, single-purpose token (e.g. signed GlobalID / message_verifier) rather than a permanent token that authorizes orders, credit purchases, and preference changes all at once. Consider requiring a real session for credit purchases and order edits.

Context: the token is currently unscoped (one uid authorizes order read/write + email prefs + credit purchase) and never expires.

Metadata

Metadata

Assignees

No one assigned

    Labels

    devopsrubyPull requests that update Ruby code

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions