Skip to content

feat: set default HSTS and CSP headers for direct-exposure deployments (#14)#20

Open
mgoldsborough wants to merge 1 commit intomainfrom
fix/issue-14-default-hsts-csp
Open

feat: set default HSTS and CSP headers for direct-exposure deployments (#14)#20
mgoldsborough wants to merge 1 commit intomainfrom
fix/issue-14-default-hsts-csp

Conversation

@mgoldsborough
Copy link
Copy Markdown
Contributor

Summary

  • Previous policy of delegating HSTS/CSP to a reverse proxy left direct-exposure self-hosted deployments with no hardening. Direct-HTTPS is a supported topology, so defaults should protect it.
  • Added conservative defaults in `securityHeaders()`:
    • HSTS: `max-age=31536000; includeSubDomains` (no `preload` — that is a deliberate operator choice)
    • CSP: `default-src 'none'; frame-ancestors 'none'; base-uri 'none'` (does not affect JSON/SSE; bundle UI HTML is consumed via `fetch+srcdoc` so the response CSP does not break the iframe bridge)
  • Overrideable via `NB_HSTS` / `NB_CSP` env vars or middleware options. Env var takes precedence over option. Empty string disables the header — preserves the "delegate to proxy" behavior for operators who want it.

Test plan

  • 13 unit tests covering defaults, option override, env var override, empty-string disable, POST and 404 paths
  • `bun run lint` / `bun run check` — clean
  • README updated with new env var documentation

Closes #14

#14)

The previous stance of "HSTS/CSP belong on the reverse proxy" leaves
self-hosted OSS deployments with no hardening when no proxy sits in
front. Direct-exposure HTTPS is a supported topology, so the defaults
should protect it.

Add conservative defaults in securityHeaders():
- HSTS: max-age=31536000; includeSubDomains (no preload — that is a
  deliberate operator choice)
- CSP:  default-src 'none'; frame-ancestors 'none'; base-uri 'none'
  (no effect on JSON/SSE; bundle UI HTML is consumed via fetch+srcdoc
  so the response CSP does not break the iframe bridge, but does
  protect anyone opening that HTML directly)

Operators who terminate TLS at a proxy that already emits these
headers can disable them with NB_HSTS="" / NB_CSP="", or override to
a stricter/looser value via env var or the middleware option. Env var
takes precedence over option so ops can change the runtime policy
without a code change.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add default HSTS and CSP headers for direct-exposure deployments

1 participant