Close out issue 001: document CSRF/reverse-proxy requirement
The app-side fix (CSRF_TRUSTED_ORIGINS, SECURE_PROXY_SSL_HEADER in
settings.py) was already committed as d458cd3 after the first Cloud-VM-1
deployment hit "CSRF verification failed" on login behind Apache. This
finishes the rest of that issue's checklist: documents
DJANGO_CSRF_TRUSTED_ORIGINS in deploy/env.example, adds the required
X-Forwarded-Proto header to the Apache/Caddy examples in
cloud_agent_deploy.md (plus a checklist item that verifies via an actual
login, not just an unauthenticated capabilities curl), and adds the same
proxy-agnostic guidance to docs/deployment.md.
Also introduces issues/, a tracked one-file-per-issue log for the project
going forward.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
parent
d458cd3673
commit
f2f2a9c96b
5 changed files with 114 additions and 3 deletions
71
issues/001-csrf-behind-reverse-proxy.md
Normal file
71
issues/001-csrf-behind-reverse-proxy.md
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
# 001 — CSRF verification fails behind a TLS-terminating reverse proxy
|
||||
|
||||
**Status:** Fixed
|
||||
|
||||
## Description
|
||||
|
||||
Deploying Daybook behind Apache (TLS-terminating reverse proxy → plain HTTP
|
||||
to the container) on `cloud-vm-1`, login failed with:
|
||||
|
||||
```
|
||||
Forbidden (403)
|
||||
CSRF verification failed. Request aborted.
|
||||
```
|
||||
|
||||
**Root cause:** `daybook_project/settings.py` set `ALLOWED_HOSTS` from an env
|
||||
var but never set `CSRF_TRUSTED_ORIGINS` or `SECURE_PROXY_SSL_HEADER`. Without
|
||||
the latter, Django has no way to know the original request was HTTPS — the
|
||||
proxy terminates TLS and forwards plain HTTP — so it treats every request as
|
||||
insecure, which breaks CSRF checks on any POST (including login) once a
|
||||
browser connects over `https://`.
|
||||
|
||||
This isn't specific to `cloud-vm-1` — it'll happen on any reverse-proxied
|
||||
deployment (Apache, Nginx, Traefik, a cloud load balancer), which is the
|
||||
explicitly recommended setup in `deploy/cloud_agent_deploy.md` §8. The
|
||||
runbook doesn't mention CSRF or proxy-awareness anywhere.
|
||||
|
||||
## Fix
|
||||
|
||||
**App (`daybook_project/settings.py`):**
|
||||
|
||||
```python
|
||||
CSRF_TRUSTED_ORIGINS = [origin.strip() for origin in os.environ.get("DJANGO_CSRF_TRUSTED_ORIGINS", "").split(",") if origin.strip()]
|
||||
SECURE_PROXY_SSL_HEADER = ("HTTP_X_FORWARDED_PROTO", "https")
|
||||
```
|
||||
|
||||
Committed locally as `d458cd3` ("Fix CSRF failure behind a TLS-terminating
|
||||
reverse proxy") — **needs to be pushed to `main`**, the deploy agent that
|
||||
made this fix didn't have push access to the Forgejo repo.
|
||||
|
||||
**Deploy env (`deploy/env.example` / runbook):** needs a new var,
|
||||
`DJANGO_CSRF_TRUSTED_ORIGINS`, set to the public HTTPS origin, e.g.:
|
||||
|
||||
```
|
||||
DJANGO_CSRF_TRUSTED_ORIGINS=https://daybook.example.com
|
||||
```
|
||||
|
||||
**Proxy config:** `SECURE_PROXY_SSL_HEADER` only works if the proxy actually
|
||||
sends that header. The Apache example in `cloud_agent_deploy.md` §8 is
|
||||
missing it — needs:
|
||||
|
||||
```apache
|
||||
RequestHeader set X-Forwarded-Proto "https"
|
||||
```
|
||||
|
||||
inside the `<VirtualHost *:443>` block (requires `a2enmod headers`). The
|
||||
equivalent for Nginx is `proxy_set_header X-Forwarded-Proto $scheme;`, worth
|
||||
adding to `docs/deployment.md`'s reverse-proxy notes too since that doc
|
||||
mentions Nginx/Traefik as options without this caveat.
|
||||
|
||||
## Resolution
|
||||
|
||||
- [x] Pushed commit `d458cd3` to `main`.
|
||||
- [x] Added `DJANGO_CSRF_TRUSTED_ORIGINS` to `deploy/env.example` with an
|
||||
explanatory comment.
|
||||
- [x] Updated `cloud_agent_deploy.md` §8's Apache example to include
|
||||
`RequestHeader set X-Forwarded-Proto "https"`, plus a Caddy equivalent
|
||||
and a checklist item that verifies by actually logging in through the
|
||||
proxy (not just curling `/api/capabilities`, which is unauthenticated
|
||||
GET and wouldn't have caught this).
|
||||
- [x] Updated `docs/deployment.md`'s "Reverse Proxy Notes" and checklist with
|
||||
the same requirement, plus an Nginx/Apache/Caddy header cheat sheet.
|
||||
5
issues/README.md
Normal file
5
issues/README.md
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
# Issues
|
||||
|
||||
One file per issue: `NNN-short-slug.md`, numbered sequentially. Each file
|
||||
has a title, status (Open / Fixed / By design), description, and resolution
|
||||
once closed.
|
||||
Loading…
Add table
Add a link
Reference in a new issue