feat: add defense-in-depth security-header layer

Attaches a SetResponseHeaderLayer stack to create_router_with_state
(not main.rs) so tests observe the same response shape as production.
`if_not_present` mode so per-route overrides (magic.rs already sets
its own Referrer-Policy) are preserved.

Sets: X-Content-Type-Options, X-Frame-Options, Referrer-Policy,
Content-Security-Policy, Permissions-Policy. HSTS is deliberately
omitted until TLS termination is in place — a cached max-age on a
plain-HTTP deployment is irreversible.

CSP uses 'unsafe-inline' for script/style since templates contain
inline scripts; revisit if any user input ever renders unescaped.

Removes #[ignore] from the 10 attack-confirming header tests; two
regression anchors (no-HSTS, no-duplicated magic header) were already
green.
This commit is contained in:
2026-04-22 09:33:46 +02:00
parent 34aa633d32
commit f3d0380dbd
3 changed files with 52 additions and 15 deletions
+1 -1
View File
@@ -19,7 +19,7 @@ uuid.workspace = true
serde.workspace = true
serde_json.workspace = true
toml.workspace = true
tower-http = { version = "0.6", features = ["limit", "trace"] }
tower-http = { version = "0.6", features = ["limit", "trace", "set-header"] }
tokio-stream = { version = "0.1", features = ["sync"] }
futures-util = "0.3"
rand = "0.8"