Default security headers + opt-in Secure cookies

Default security headers + opt-in Secure cookies

#7 in tonybierman/arium — merged 2026-05-25

Hardens arium::install for all consumers, closing a batch of nuclei dynamic-scan findings against the running example.

Security response headers

A behavior-safe static set is now stamped on every response (added as the outermost layer, so it also covers short-circuited responses like rate-limit 429s):

Header Value
X-Content-Type-Options nosniff
Referrer-Policy strict-origin-when-cross-origin
X-Frame-Options SAMEORIGIN
Cross-Origin-Opener-Policy same-origin
X-Permitted-Cross-Domain-Policies none
Permissions-Policy camera=(), microphone=(), geolocation=()

X-Frame-Options: SAMEORIGIN (not DENY) lets consumers that self-embed (e.g. dx_standup) keep working while still blocking cross-origin clickjacking.

Opt-in via the builder, off by default because they're environment-specific:

  • .hsts(value) — pass arium::RECOMMENDED_HSTS in prod. Off by default so it can't pin localhost to HTTPS.
  • .content_security_policy(value) — off by default since a wrong CSP breaks Dioxus wasm hydration; the method doc ships a working starter policy.

COEP require-corp is deliberately left off — it would block the cross-origin GitHub avatars the example loads.

Cookies

  • Secure — new opt-in .cookie_secure(true) wires Secure onto the session cookie for production. Default false so plain-HTTP localhost / dx serve keeps working.
  • SameSite stays Lax, not Strict. The OAuth CSRF state + PKCE verifier live in the session (oauth.rs), and the provider callback is a cross-site top-level redirect — only Lax sends the cookie on it. Strict would break OAuth sign-in. The missing-cookie-samesite-strict nuclei finding is a false positive for redirect-based OAuth; rationale is pinned in a code comment. HttpOnly was already on.

Verification

New crates/arium/tests/security_headers.rs boots a real router through install over a TCP socket and asserts on the wire:

  • static header set present; HSTS/CSP absent until opted in
  • session cookie is Lax; HttpOnly and not Secure by default; Secure appears with .cookie_secure(true)

Full arium suite green. Both CI clippy passes (all-targets -D warnings, plus lib with the security lints) and cargo fmt --all --check clean.

🤖 Generated with Claude Code

Last updated 2026-05-26