Files
cgalo5758 0b28a9dc29 Remediate security audit findings
- Replace gorilla/csrf with net/http CrossOriginProtection
- Require valkey-password and add TLS options for session store
- End session at /logout and revoke refresh tokens
- Re-derive identity and roles from provider every five minutes
- Process each Stripe webhook event in its own Temporal workflow
- Give each outbox entry its own workflow with Temporal retries
- Guard against stale Stripe events with provider timestamps
- Derive transport security from base-url scheme
2026-09-09 13:25:43 -05:00

4.3 KiB

http-security-headers Specification

Purpose

TBD - created by archiving change security-audit-remediation. Update Purpose after archive.

Requirements

Middleware that configures cookies SHALL treat an unset attribute as "keep the library's secure default". A protection SHALL be disabled only when a caller explicitly asks for it, never as a consequence of a zero-valued field.

  • WHEN the CSRF middleware is configured without setting the cookie's Secure or HttpOnly fields
  • THEN the issued CSRF cookie SHALL carry both Secure and HttpOnly

Scenario: Development can still opt out over plain HTTP

  • WHEN the deployment environment is development and the configuration explicitly disables Secure
  • THEN the issued CSRF cookie SHALL omit Secure
  • AND that override SHALL be the only way the attribute is dropped

Requirement: The content security policy lists only sources the application loads

The script-src, style-src, and font-src directives SHALL name only origins from which the application actually loads resources. An origin that no longer serves anything to this application SHALL NOT remain authorized.

Scenario: Front-end assets are self-hosted

  • WHEN the application serves its hypermedia library and stylesheets from its own embedded static assets
  • THEN the policy's script-src SHALL permit 'self' and SHALL NOT permit any third-party content delivery network

Scenario: Script from an unlisted origin is refused

  • WHEN a page attempts to load script from an origin the policy does not name
  • THEN the user agent SHALL refuse to execute it

Requirement: Every response carries the security headers, including refusals

The security headers SHALL be applied outside any middleware that answers for the handler, so a response written by the request timeout or the body-size limit carries them like any other. A refusal SHALL NOT be the one response without them.

Scenario: A body too large is refused with the headers on

  • WHEN a request body exceeds the size limit and the limit answers 413
  • THEN the response SHALL carry the same security headers a handler's response carries

Scenario: A timed-out request is refused with the headers on

  • WHEN a request exceeds the timeout and the timeout answers 503
  • THEN the response SHALL carry the same security headers, even though the timeout handler discards headers set inside it

Requirement: Non-safe cross-origin requests are refused

The application SHALL refuse non-safe cross-origin browser requests by inspecting the request's origin, not by issuing, storing, or validating a token. A trusted origin SHALL be matched including its scheme, so that a policy naming an https origin is not satisfied by the same host over plain http.

Because safe methods are always permitted, no handler SHALL change state in response to a GET, HEAD, or OPTIONS request.

Scenario: A same-origin form post succeeds

  • WHEN a browser submits a form to the application from one of its own pages
  • THEN the request SHALL be allowed
  • AND it SHALL succeed with no token present in the form, in a header, or in a cookie

Scenario: A cross-site post is refused

  • WHEN a non-safe request arrives from another site
  • THEN the application SHALL refuse it with 403
  • AND the response body SHALL identify the refusal as a CSRF check failure, so client-side code can preserve the person's input

Scenario: A trusted origin is scheme-sensitive

  • WHEN an origin is trusted as https://host and a request arrives from http://host
  • THEN the request SHALL be refused

Scenario: A misconfigured trusted origin fails at startup

  • WHEN a configured trusted origin carries no scheme
  • THEN startup SHALL fail with an error naming that origin, rather than silently dropping it and leaving the deployment to reject its own posts

Scenario: A signature-verified endpoint bypasses the check

  • WHEN a provider webhook that authenticates its caller by signature receives a cross-origin delivery
  • THEN cross-origin protection SHALL NOT refuse it
  • AND the endpoint's own signature verification SHALL still decide the outcome