Shipped nginx/Netlify configs set no CSP, frame-ancestors or referrer policy #44

Closed
opened 2026-09-12 01:51:10 -04:00 by jared · 1 comment
Owner

Severity: medium · Type: security · Confidence: high

Location: docker-nginx.conf:1-19, netlify.toml:1-40, index.html (no <meta http-equiv="Content-Security-Policy">)

Problem

the embed code treats CSP as its primary control — EMBED_SANDBOX is documented as
"Defense-in-depth on top of the CSP frame-src allowlist"
(src/app/components/url-preview/UrlPreviewCard.tsx:621-624) — and LOTUS_TODO.md reasons about a
prod frame-src 'self' https:. But no CSP exists anywhere in the repo: the Docker nginx server block
emits no headers at all, netlify.toml only has redirects, and index.html has no CSP meta tag. Any
deployment built from this repo (the Dockerfile is the documented path) therefore runs with no
frame-src restriction, no frame-ancestors (the client is framable → clickjacking against the
message composer / verification flows), no Referrer-Policy, and no X-Content-Type-Options. The
production CSP evidently lives in infrastructure outside this repo, which means it is silently absent
for every other deployment and is not covered by any check here.

How to trigger

docker build . && docker run …, then curl -I http://localhost/ — no security headers; embed the app in a third-party <iframe> — it renders.

Suggested fix

add add_header directives to docker-nginx.conf (CSP with an explicit frame-src
allowlist matching videoEmbed.ts, frame-ancestors 'none', Referrer-Policy: no-referrer,
X-Content-Type-Options: nosniff) and the equivalent [[headers]] block in netlify.toml, so the
control the client code depends on ships with the client.


Filed from the September 2026 client audit (branch lotus @ 4bea4895).

**Severity:** medium · **Type:** security · **Confidence:** high **Location:** `docker-nginx.conf:1-19`, `netlify.toml:1-40`, `index.html` (no `<meta http-equiv="Content-Security-Policy">`) ### Problem the embed code treats CSP as its primary control — `EMBED_SANDBOX` is documented as "Defense-in-depth **on top of the CSP frame-src allowlist**" (`src/app/components/url-preview/UrlPreviewCard.tsx:621-624`) — and `LOTUS_TODO.md` reasons about a prod `frame-src 'self' https:`. But no CSP exists anywhere in the repo: the Docker nginx server block emits no headers at all, `netlify.toml` only has redirects, and `index.html` has no CSP meta tag. Any deployment built from this repo (the Dockerfile is the documented path) therefore runs with no `frame-src` restriction, no `frame-ancestors` (the client is framable → clickjacking against the message composer / verification flows), no `Referrer-Policy`, and no `X-Content-Type-Options`. The production CSP evidently lives in infrastructure outside this repo, which means it is silently absent for every other deployment and is not covered by any check here. ### How to trigger `docker build . && docker run …`, then `curl -I http://localhost/` — no security headers; embed the app in a third-party `<iframe>` — it renders. ### Suggested fix add `add_header` directives to `docker-nginx.conf` (CSP with an explicit `frame-src` allowlist matching `videoEmbed.ts`, `frame-ancestors 'none'`, `Referrer-Policy: no-referrer`, `X-Content-Type-Options: nosniff`) and the equivalent `[[headers]]` block in `netlify.toml`, so the control the client code depends on ships with the client. --- _Filed from the September 2026 client audit (branch `lotus` @ 4bea4895)._
jared added this to the Audit 2026-09 · Medium & Low milestone 2026-09-12 01:51:10 -04:00
jared added the bugpriority: mediumsecurityarea: build-ci labels 2026-09-12 01:51:10 -04:00
jared self-assigned this 2026-09-12 01:51:10 -04:00
Author
Owner

Production already sent a full CSP (frame-ancestors 'none', HSTS, nosniff, referrer policy), so the original finding only applied to the shipped Docker/Netlify configs — fixed in 039b74c2 (#95). While verifying, found the real problem: the host's nginx config was older than the tracked one because LXC 106's webhook config had lost the matrix-deploy hook on 2026-05-21, so nothing from the matrix repo had deployed there since (widget-friendly frame-src 'self' https: from July never landed). Fixed today: tracked nginx.conf installed and reloaded (live headers verified), deploy helpers reinstalled, hooks.json restored as the union of all three hooks (matrix@d3ee2e2), webhook restarted.

Production already sent a full CSP (frame-ancestors 'none', HSTS, nosniff, referrer policy), so the original finding only applied to the shipped Docker/Netlify configs — fixed in 039b74c2 (#95). While verifying, found the real problem: the host's nginx config was older than the tracked one because LXC 106's webhook config had lost the matrix-deploy hook on 2026-05-21, so nothing from the matrix repo had deployed there since (widget-friendly `frame-src 'self' https:` from July never landed). Fixed today: tracked nginx.conf installed and reloaded (live headers verified), deploy helpers reinstalled, hooks.json restored as the union of all three hooks (matrix@d3ee2e2), webhook restarted.
jared closed this issue 2026-09-15 22:24:43 -04:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
2026-11-14
Dependencies

No dependencies set.

Reference: LotusGuild/cinny#44