Introduce .agents/ (PLAN.md with locked architectural anchors, phase roadmap under phases/todo/) and AGENTS.md rules for agents working in the repo. Queues the pending phases: fix history XSS, simulate fetch commands, and nginx security headers.
2.4 KiB
Phase 03 — Security headers on every location (audit M-4)
Story: n/a
Context: .agents/PLAN.md §3 (serving + edge), .agents/remediation_plan.md
findings M-4 (headers) and L-2 (server_tokens, included as a one-liner in
the same file)
Objective
Fix the nginx add_header inheritance trap: the location = /index.html
and the hashed-asset location each define their own cache add_header
directives, so they lose the server-level security headers (CSP,
X-Frame-Options, X-Content-Type-Options, Referrer-Policy). Extract the four
security headers into a snippet and include it in every location, so
every response class carries the full header set. Also set
server_tokens off; (L-2) in the same pass.
Dependencies
— (none)
Tasks
01_extract_header_snippet.md— Createnginx-security-headers.inc, wire it into the Dockerfile, andincludeit in the server block and both header-defining locations (plusserver_tokens off;).02_add_header_verification.md— Addscripts/check-headers.shthat builds and runs the real image and asserts all four headers on/,/index.html, and a hashed asset.
Testing & Quality
- Unit/integration: the container-based header check (task 02) is the integration test. It must assert all four headers on each of the three response classes.
- Coverage: >90% on new/modified config (all three location paths exercised by the check script).
- The Playwright E2E suite is unaffected (its webServer is plain python, not nginx) and must stay green.
Completion Criteria
nginx-security-headers.incexists and holds the fouradd_header … always;linesnginx.confhas no inline securityadd_headerlines (only theinclude), and both header-defining locationsincludethe snippetserver_tokens off;present in theserverblockscripts/check-headers.shruns the real image and printsHEADER CHECK PASSED(all four headers on/,/index.html, and a hashed asset)./build.sh && npm testfully green- no behavior change in completed work (terminal, vim, achievements, menu)
Out of scope (separate, unphased): L-1 HSTS — that is an edge/Caddy
responsibility (the container serves plain HTTP on 8080). Verify at the edge
manually: curl -sI https://reeseapps.com/ | grep -i strict-transport. Do
not add HSTS inside the 8080 container.