Skip to content

Public-form CSRF tokens (HMAC + anon-cookie binding) #176

@tayebmokni

Description

@tayebmokni

Summary

Implement public-form CSRF tokens per doc 13 §10.1 for comments, plugin-provided contact forms, and search-tracking POSTs. Each form renders with a token that is the HMAC of (anon-id || form-id || timestamp) signed with auth.session_signing_key. Anon-session is an opaque cookie __site_anon (HttpOnly, SameSite=Lax, Secure, Path=/, max-age 30d). Submit verifies both the token HMAC and the anon-cookie binding. Origin/Referer must match the site origin for state-changing POSTs. High-stakes forms (e.g., password recovery) use single-use tokens.

Design reference

  • docs/13-security-baseline.md §10.1 (public-form CSRF tokens), §10.2 (GraphQL mutations)

Acceptance criteria

  • __site_anon cookie set on first visit (HttpOnly, SameSite=Lax, Secure, Path=/, max-age 30d, random UUID)
  • Token = HMAC(anon-id || form-id || timestamp, auth.session_signing_key), 12h validity
  • Server verifies token HMAC + cookie binding + timestamp window on submit
  • Origin or Referer matches site origin for state-changing POSTs (rejects mismatched)
  • Single-use enforcement for high-stakes forms (e.g., password recovery) via replay cache
  • Form helper API for emitting the hidden token field
  • Public GraphQL mutations require the public-form token or are blocked
  • Tests cover happy path, expired token, missing cookie, bad origin, replayed single-use

Dependencies

#105

Complexity

M

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:apiGo HTTP API serverarea:webNext.js public sitephase:P1-cms-corePhase 1 — CMS Corepriority:P1Important — should land in phaseskill:goGo programmingskill:securitySecurity expertisetype:featNew feature or implementation tasktype:securitySecurity-related work

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions