aboutsummaryrefslogtreecommitdiffstats
path: root/AGENTS.md
diff options
context:
space:
mode:
authorgrm <grm@eyesin.space>2026-09-18 13:49:19 +0300
committergrm <grm@eyesin.space>2026-09-18 13:49:28 +0300
commitd23fe805546e992c8033d64d7177fe1454ad7716 (patch)
tree79657033b96f852f57bac5c0bf42551a8721afa8 /AGENTS.md
parentabc1898daebae33405688618caffa01cece3b850 (diff)
downloadblogspace-d23fe805546e992c8033d64d7177fe1454ad7716.tar.gz
blogspace-d23fe805546e992c8033d64d7177fe1454ad7716.tar.bz2
blogspace-d23fe805546e992c8033d64d7177fe1454ad7716.zip
Security: Send security headers; refuse to frame the dashboard
Pages carried no X-Content-Type-Options, no Referrer-Policy, and the dashboard could be framed by any site (clickjacking a superadmin's delete buttons). Every response now says nosniff and strict-origin-when-cross-origin, and the management paths on the root host add X-Frame-Options: DENY plus a CSP of frame-ancestors, base-uri, form-action and object-src — the directives that do not touch the dashboard's inline scripts, which are a product constraint. Blog pages get no framing rule: they are the owner's content and may be embedded on purpose. HSTS moves into the same helper. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Sd8UPWrvyYCLj97JexNw3A
Diffstat (limited to 'AGENTS.md')
-rw-r--r--AGENTS.md9
1 files changed, 8 insertions, 1 deletions
diff --git a/AGENTS.md b/AGENTS.md
index 9764661..986d21d 100644
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -147,7 +147,14 @@ internal/web/ server.go (host router, middleware, render helpers)
logins are logged with the username and address, and the login body is
capped at `maxLoginBody` (64 KB) since it is the one POST outside
`guardPOST`. `s.clientIP` is the peer address, or the last
- `X-Forwarded-For` hop with `TRUST_PROXY` (earlier entries are forgeable). Flood
+ `X-Forwarded-For` hop with `TRUST_PROXY` (earlier entries are forgeable).
+ `secureHeaders` (`ServeHTTP`) puts `nosniff`, a `Referrer-Policy` and,
+ with `HTTPS`, HSTS on every response; the management paths on the root
+ host (`managementPaths` — add a new top-level management prefix there
+ as well as to `reservedPageSlugs`) also get `X-Frame-Options: DENY` and
+ a CSP of `frame-ancestors`/`base-uri`/`form-action`/`object-src` only —
+ no `script-src`, the dashboard's inline scripts are a product
+ constraint. Public blog pages carry no framing rule (owner content). Flood
control for everything else stays at the reverse proxy (`limit_req`).
- **Templates**: each page file is parsed together with its layout
(`layouts/dashboard.html` or `layouts/blog.html` for `blog/*`) and all