Files
ducoterra a2f331e526
Build and Push Container / build-and-push (push) Successful in 11s
Add phased-execution planning structure
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.
2026-09-18 17:23:41 -04:00

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

  1. 01_extract_header_snippet.md — Create nginx-security-headers.inc, wire it into the Dockerfile, and include it in the server block and both header-defining locations (plus server_tokens off;).
  2. 02_add_header_verification.md — Add scripts/check-headers.sh that 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.inc exists and holds the four add_header … always; lines
  • nginx.conf has no inline security add_header lines (only the include), and both header-defining locations include the snippet
  • server_tokens off; present in the server block
  • scripts/check-headers.sh runs the real image and prints HEADER CHECK PASSED (all four headers on /, /index.html, and a hashed asset)
  • ./build.sh && npm test fully 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.