# `Macaw.Plug.SecurityHeaders`
[🔗](https://github.com/dcoai/macaw_plug/blob/v0.1.4/lib/macaw/plug/security_headers.ex#L1)

A strict Content-Security-Policy and the standard security headers.

    plug Macaw.Plug.SecurityHeaders

**The default policy is closed:** everything from the app's own origin,
nothing inline, nothing evaluated, nothing framed:

    default-src 'self'; script-src 'self'; style-src 'self';
    img-src 'self' data:; font-src 'self'; connect-src 'self';
    object-src 'none'; base-uri 'none'; form-action 'self';
    frame-ancestors 'none'

A host changes a directive only by naming it, `csp: [img_src: "'self'"]`,
so every loosening is visible in the host's code.

**A host's own inline script** is allowed by its SHA-256 hash, never by
`'unsafe-inline'`. The policy is written just before the response is sent,
so a controller that renders such a script adds its hash on the way:

    conn |> Macaw.Plug.SecurityHeaders.put_script_hash(script_body)

**Also set:** `x-content-type-options: nosniff`, `referrer-policy:
strict-origin-when-cross-origin`, `x-frame-options: DENY` (for browsers
that predate `frame-ancestors`), `cross-origin-opener-policy:
same-origin`, a `permissions-policy` that turns off camera, microphone,
geolocation, payment and USB, and over https
`strict-transport-security: max-age=31536000`. Each can be replaced with
`headers: %{"name" => value}`, or removed with `nil`. This replaces
Phoenix's `put_secure_browser_headers`.

# `hash`

```elixir
@spec hash(String.t()) :: String.t()
```

A script body's CSP hash source, `'sha256-…'`.

# `policy`

```elixir
@spec policy(keyword(String.t()), [String.t()]) :: String.t()
```

The policy string for directives (the defaults, or as `init/1` merged
them) and script hashes, which are added to `script-src`.

# `put_script_hash`

```elixir
@spec put_script_hash(Plug.Conn.t(), String.t()) :: Plug.Conn.t()
```

Allows an inline script on this response by its SHA-256 hash. Takes the
script's body (the text between `<script>` and `</script>`), exactly.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
