# http-security-headers Specification ## Purpose TBD - created by archiving change security-audit-remediation. Update Purpose after archive. ## Requirements ### Requirement: Cookie protections are on unless explicitly disabled 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. #### Scenario: An unconfigured CSRF cookie keeps Secure and HttpOnly - **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