aboutsummaryrefslogtreecommitdiffstats
path: root/README.md
diff options
context:
space:
mode:
authorgrm <grm@eyesin.space>2026-09-18 13:47:49 +0300
committergrm <grm@eyesin.space>2026-09-18 13:47:49 +0300
commit3eeaa6d9a33f9294ade64c8ff26144fba86a379e (patch)
tree1c4bf44884ea59f7e3d9ca12008846f08bf72d16 /README.md
parent254733b0566830a46e5a44c2d3127f57bfaceb65 (diff)
downloadblogspace-3eeaa6d9a33f9294ade64c8ff26144fba86a379e.tar.gz
blogspace-3eeaa6d9a33f9294ade64c8ff26144fba86a379e.tar.bz2
blogspace-3eeaa6d9a33f9294ade64c8ff26144fba86a379e.zip
Security: Add HTTPS and TRUST_PROXY settings
The app only ever speaks plain HTTP, so it could not know the site was served over TLS: generated links were http:// (the /webadmin bounce from a blog host sent the login page over http), the session cookie was never Secure and nothing sent HSTS. HTTPS=true fixes all three; ClearSessionCookie now uses the same attributes as the set, since a browser only replaces a cookie whose Secure flag matches. TRUST_PROXY=true makes the client address the last X-Forwarded-For entry — the one our proxy appended — so throttling and the log see real addresses instead of the proxy's; earlier entries are whatever the client sent and are ignored. Production startup warns when HTTPS is off. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Sd8UPWrvyYCLj97JexNw3A
Diffstat (limited to 'README.md')
-rw-r--r--README.md5
1 files changed, 4 insertions, 1 deletions
diff --git a/README.md b/README.md
index ec14555..ba79190 100644
--- a/README.md
+++ b/README.md
@@ -90,6 +90,8 @@ Go changes need a restart.
| `JWT_SECRET` | — | **Required** outside dev; long random string (`openssl rand -hex 32`) |
| `SUPERADMIN_USERNAME` / `SUPERADMIN_PASSWORD` | `admin` / — | Created on first start if no superadmin exists |
| `MAX_UPLOAD_MB` | `10` | Per-file upload limit; the superadmin can override it per blog in `/admin/` |
+| `HTTPS` | `false` | The proxy terminates TLS: generated links are `https://`, the session cookie is `Secure`, HSTS is sent. **Set it in production.** |
+| `TRUST_PROXY` | `false` | Take the client address from the last `X-Forwarded-For` entry (the one your proxy wrote) for rate limiting and the log. Set it when the app is only reachable through your proxy. |
| `DEV` | `false` | Hot-reload templates, allow missing secrets |
Migrations run automatically at startup, for the control database and for every blog database.
@@ -103,7 +105,8 @@ docker compose up --build -d
The app listens on `127.0.0.1:8080` (see `APP_PORT`); put a reverse proxy in
front that terminates TLS and forwards **both** the root domain and the wildcard
-with the original `Host` header. DNS needs two records: `A example.com` and
+with the original `Host` header. Keep `HTTPS=true` and `TRUST_PROXY=true` in
+`.env` for that setup (the sample has them). DNS needs two records: `A example.com` and
`A *.example.com` (or CNAMEs) pointing at the proxy.
nginx example: