fabro/lib/crates
Bryan Helmkamp 13f612b111
feat(server): emit baseline HTTP security headers on every response
fabro-server previously sent no security headers beyond content-type
and cache-control. Add a tower middleware that fills in a conservative
default set on every response, preserving any header the handler
already set so routes can still override.

Always applied:
  - X-Content-Type-Options: nosniff
  - X-Frame-Options: DENY
  - Referrer-Policy: strict-origin-when-cross-origin
  - Cross-Origin-Opener-Policy: same-origin
  - Cross-Origin-Resource-Policy: same-origin
  - Permissions-Policy: (deny sensor/payment/xr APIs)
  - X-Download-Options: noopen
  - X-Permitted-Cross-Domain-Policies: none
  - X-XSS-Protection: 0  (current OWASP guidance — the legacy filter
    has known bypasses; CSP is the proper replacement)
  - Cache-Control: no-store  (default; asset routes keep their own)
  - Pragma: no-cache
  - Vary: Accept-Encoding

Applied only when the request reached an HTTPS edge (direct TLS or
X-Forwarded-Proto: https from a reverse proxy):
  - Strict-Transport-Security: max-age=63072000; includeSubDomains

CSP is deliberately not included — it needs a dedicated audit of the
SPA's script/style/font/connect sources and isn't a drop-in header.
Filed as a separate follow-up.

Tests cover each applied header, non-override behavior against the
static-file cache-control, HSTS gating on X-Forwarded-Proto (including
the chained "https, http" leftmost-wins case), and an integration test
against a live router confirming both API and SPA responses carry the
headers.
2026-04-18 15:59:32 -04:00
..
fabro-agent ci: switch clippy to pinned nightly, clean up workspace lints 2026-04-16 18:59:11 -04:00
fabro-api refactor(http): centralize reqwest behind fabro-http 2026-04-12 11:48:54 -04:00
fabro-auth fix: resolve test failures and clippy warnings across workspace 2026-04-15 11:02:20 -04:00
fabro-checkpoint refactor(async): lint std::process::Command across all targets 2026-04-12 13:35:57 -04:00
fabro-cli test: preserve LLVM_PROFILE_FILE across env_clear in CLI tests 2026-04-18 15:05:32 -04:00
fabro-config ci: switch clippy to pinned nightly, clean up workspace lints 2026-04-16 18:59:11 -04:00
fabro-core ci: switch clippy to pinned nightly, clean up workspace lints 2026-04-16 18:59:11 -04:00
fabro-devcontainer fix: wrap propagated io errors with anyhow context across prod code 2026-04-17 11:44:38 -04:00
fabro-github Merge remote-tracking branch 'origin/main' 2026-04-12 13:43:38 -04:00
fabro-graphviz ci: switch clippy to pinned nightly, clean up workspace lints 2026-04-16 18:59:11 -04:00
fabro-hooks fix: simplify fabro-http crate and fix correctness issues 2026-04-12 12:20:55 -04:00
fabro-http fix: simplify fabro-http crate and fix correctness issues 2026-04-12 12:20:55 -04:00
fabro-interview fix: wrap propagated io errors with anyhow context across prod code 2026-04-17 11:44:38 -04:00
fabro-llm fix(llm): send Gemini API key via x-goog-api-key header 2026-04-18 04:32:23 -04:00
fabro-macros refactor(settings): stage 6.3b shrink server runtime types + delete Combine 2026-04-09 18:27:46 -04:00
fabro-mcp fix: simplify fabro-http crate and fix correctness issues 2026-04-12 12:20:55 -04:00
fabro-model wip 2026-04-16 13:13:09 -04:00
fabro-oauth Add typed provider credential auth flow 2026-04-12 22:10:11 -04:00
fabro-proc fmt: apply nightly rustfmt after merge 2026-04-11 13:43:30 -04:00
fabro-retro ci: switch clippy to pinned nightly, clean up workspace lints 2026-04-16 18:59:11 -04:00
fabro-sandbox deps: bump rand 0.8 → 0.9 (#163) 2026-04-17 07:57:10 -04:00
fabro-server feat(server): emit baseline HTTP security headers on every response 2026-04-18 15:59:32 -04:00
fabro-slack refactor(http): centralize reqwest behind fabro-http 2026-04-12 11:48:54 -04:00
fabro-spa Update SPA 2026-04-16 17:35:37 -04:00
fabro-store ci: switch clippy to pinned nightly, clean up workspace lints 2026-04-16 18:59:11 -04:00
fabro-telemetry fix: wrap propagated io errors with anyhow context across prod code 2026-04-17 11:44:38 -04:00
fabro-template refactor(async): lint std::process::Command across all targets 2026-04-12 13:35:57 -04:00
fabro-test test: preserve LLVM_PROFILE_FILE across env_clear in CLI tests 2026-04-18 15:05:32 -04:00
fabro-tracker refactor(http): centralize reqwest behind fabro-http 2026-04-12 11:48:54 -04:00
fabro-types ci: switch clippy to pinned nightly, clean up workspace lints 2026-04-16 18:59:11 -04:00
fabro-util fix: wrap propagated io errors with anyhow context across prod code 2026-04-17 11:44:38 -04:00
fabro-validate fmt: apply nightly rustfmt after merge 2026-04-11 13:43:30 -04:00
fabro-vault fix: wrap propagated io errors with anyhow context across prod code 2026-04-17 11:44:38 -04:00
fabro-workflow test(harness): flush workflow store events before returning 2026-04-18 09:44:54 -04:00