nginx: security headers on every response (closes #18) #70

Merged
clawbot merged 1 commits from fix/nginx-security-headers into next 2026-09-29 10:22:13 +02:00
Collaborator

nginx sent none of the security headers REPO_POLICIES.md requires. security-headers.conf sets all six with always, so errors carry them too; nginx.conf includes it at server level and again in /assets/, whose own add_header would drop them. nginx hides the copies netwatch-server sets, so /api/ and the health check carry each header once, with nginx's value.

What the diff does not show:

  • The policy follows the built dist/: no inline script or style, and a data: favicon. The one inline style, the status dot's grey in src/main.js, is now a class of the same colour.
  • connect-src is *, not the hosts in src/main.js: the browser checks every redirect a probe follows, and the Google Cloud, Backblaze and S3 hosts redirect elsewhere. Under a list, the redirected S3 probe was blocked.
  • On /api/ the content security policy is now the page's, not the backend's default-src 'none', and Permissions-Policy names more features.
  • I ran the image with a headless browser in a container. Every kind of response (page, asset, 404, 502 with the backend down, /api/, health check) carried each header once; the sparklines filled for WAN hosts, a report reached the backend, and the browser reported no policy violation. The Hetzner and S3 Bahrain hosts did not answer from this host's network; the policy blocked nothing.

Deviation: one line of src/main.js changed, to avoid 'unsafe-inline'.
Judgement call: Referrer-Policy: no-referrer, stricter than required, as the backend already sends.
Judgement call: HSTS without preload.
Unverified: the headless browser loads no favicon; img-src data: rests on the build output.

Model: opus-5-5

nginx sent none of the security headers `REPO_POLICIES.md` requires. `security-headers.conf` sets all six with `always`, so errors carry them too; `nginx.conf` includes it at server level and again in `/assets/`, whose own `add_header` would drop them. nginx hides the copies `netwatch-server` sets, so `/api/` and the health check carry each header once, with nginx's value. What the diff does not show: - The policy follows the built `dist/`: no inline script or style, and a `data:` favicon. The one inline style, the status dot's grey in `src/main.js`, is now a class of the same colour. - `connect-src` is `*`, not the hosts in `src/main.js`: the browser checks every redirect a probe follows, and the Google Cloud, Backblaze and S3 hosts redirect elsewhere. Under a list, the redirected S3 probe was blocked. - On `/api/` the content security policy is now the page's, not the backend's `default-src 'none'`, and `Permissions-Policy` names more features. - I ran the image with a headless browser in a container. Every kind of response (page, asset, 404, 502 with the backend down, `/api/`, health check) carried each header once; the sparklines filled for WAN hosts, a report reached the backend, and the browser reported no policy violation. The Hetzner and S3 Bahrain hosts did not answer from this host's network; the policy blocked nothing. Deviation: one line of `src/main.js` changed, to avoid `'unsafe-inline'`. Judgement call: `Referrer-Policy: no-referrer`, stricter than required, as the backend already sends. Judgement call: HSTS without `preload`. Unverified: the headless browser loads no favicon; `img-src data:` rests on the build output. Model: opus-5-5
clawbot added the needs-review label 2026-09-29 09:26:48 +02:00
clawbot self-assigned this 2026-09-29 09:26:48 +02:00
clawbot added 1 commit 2026-09-29 09:44:59 +02:00
nginx: security headers on every response (closes #18)
check / check (push) Successful in 1m13s
28d99e89d0
nginx sent none of the security headers REPO_POLICIES.md requires.
security-headers.conf now sets all six with always, included at server
level and again in /assets/, whose own add_header would otherwise drop
them. nginx hides the copies netwatch-server sets, so /api/ and the
health check carry each header once. The content security policy
allows no inline script or style; the host row's status dot took its
grey from a style attribute, now a class. connect-src is * because
several probed hosts redirect to other hosts and the browser checks
every redirect against it. Referrer-Policy is no-referrer, as the
backend already sends.

Model: opus-5-5
clawbot force-pushed fix/nginx-security-headers from 1819142cce to 28d99e89d0 2026-09-29 09:44:59 +02:00 Compare
Author
Collaborator

PASS: the change meets the definition of done of #18 as updated, and I found no defects in it.

Model: opus-5-5

PASS: the change meets the definition of done of https://git.eeqj.de/sneak/netwatch/issues/18 as updated, and I found no defects in it. Model: opus-5-5
clawbot merged commit d81da05748 into next 2026-09-29 10:22:13 +02:00
clawbot deleted branch fix/nginx-security-headers 2026-09-29 10:22:13 +02:00
clawbot removed the needs-review label 2026-09-29 10:22:13 +02:00
Sign in to join this conversation.
No Reviewers
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: sneak/netwatch#70