How to set security headers

View Source

livery_security_headers is a middleware that adds a basic set of security headers to responses (X-Content-Type-Options, X-Frame-Options, Referrer-Policy, Strict-Transport-Security, and Content-Security-Policy if you ask for it). You need it when you want these headers on every response of your service without setting them in each handler.

Add it to the stack

With an empty config it uses safe defaults:

Stack = [
    {livery_security_headers, #{}}
    %% ... handler
].

Headers sent by default:

  • X-Content-Type-Options: nosniff
  • X-Frame-Options: DENY
  • Referrer-Policy: no-referrer
  • Strict-Transport-Security: max-age=31536000; includeSubDomains (HTTPS / TLS requests only)

HSTS only on secure requests

Strict-Transport-Security means nothing over plain HTTP, so it is sent only when the request is secure (scheme is https or TLS info is present). Change it or turn it off:

{livery_security_headers, #{
    hsts => #{max_age => 63072000, include_subdomains => true, preload => true}
}}

{livery_security_headers, #{hsts => false}}  %% never send HSTS

Content-Security-Policy is opt-in

A wrong CSP breaks pages, so there is no default. Set it explicitly:

{livery_security_headers, #{csp => <<"default-src 'self'">>}}

Override per header

Any key set to a value replaces the default; set it to false to drop that header entirely:

{livery_security_headers, #{
    frame_options => <<"SAMEORIGIN">>,
    referrer_policy => false
}}

Notes

  • A header the handler already set on the response is kept, so a handler can override any of these for one response.

See also