security: add headers middleware, session regeneration, and body size limits
All checks were successful
check / check (push) Successful in 6s

- Add SecurityHeaders middleware applied globally: HSTS, X-Content-Type-Options,
  X-Frame-Options, CSP, Referrer-Policy, and Permissions-Policy headers on every
  response.
- Add session regeneration (Regenerate method) after successful login to prevent
  session fixation attacks. Old session is destroyed and a new ID is issued.
- Add MaxBodySize middleware using http.MaxBytesReader to limit POST/PUT/PATCH
  request bodies to 1 MB on all form endpoints (/pages, /sources, /source/*).
- Update README.md: document SecurityHeaders and MaxBodySize in the middleware
  stack, update Security section, move security headers to completed TODO.

Closes #34, closes #38, closes #39
This commit is contained in:
clawbot
2026-03-05 02:53:45 -08:00
parent a51e863017
commit 6c6d6c2f6f
5 changed files with 127 additions and 9 deletions

View File

@@ -724,7 +724,7 @@ webhooker/
│ ├── logger/
│ │ └── logger.go # slog setup with TTY detection
│ ├── middleware/
│ │ └── middleware.go # Logging, CORS, Auth, Metrics, MetricsAuth
│ │ └── middleware.go # Logging, CORS, Auth, Metrics, MetricsAuth, SecurityHeaders, MaxBodySize
│ ├── server/
│ │ ├── server.go # Server struct, fx lifecycle, signal handling
│ │ ├── http.go # HTTP server setup with timeouts
@@ -775,14 +775,21 @@ Applied to all routes in this order:
1. **Recoverer** — Panic recovery (chi built-in)
2. **RequestID** — Generate unique request IDs (chi built-in)
3. **Logging** — Structured request logging (method, URL, status,
3. **SecurityHeaders** — Production security headers on every response
(HSTS, X-Content-Type-Options, X-Frame-Options, CSP, Referrer-Policy,
Permissions-Policy)
4. **Logging** — Structured request logging (method, URL, status,
latency, remote IP, user agent, request ID)
4. **Metrics** — Prometheus HTTP metrics (if `METRICS_USERNAME` is set)
5. **CORS** — Cross-origin resource sharing headers
6. **Timeout** — 60-second request timeout
7. **Sentry** — Error reporting to Sentry (if `SENTRY_DSN` is set;
5. **Metrics** — Prometheus HTTP metrics (if `METRICS_USERNAME` is set)
6. **CORS** — Cross-origin resource sharing headers
7. **Timeout** — 60-second request timeout
8. **Sentry** — Error reporting to Sentry (if `SENTRY_DSN` is set;
configured with `Repanic: true` so panics still reach Recoverer)
Additionally, form endpoints (`/pages`, `/sources`, `/source/*`) apply a
**MaxBodySize** middleware that limits POST/PUT/PATCH request bodies to
1 MB using `http.MaxBytesReader`, preventing oversized form submissions.
### Authentication
- **Web UI:** Cookie-based sessions using gorilla/sessions with
@@ -797,8 +804,13 @@ Applied to all routes in this order:
- Passwords hashed with Argon2id (64 MB memory cost)
- Session cookies are HttpOnly, SameSite Lax, Secure (prod only)
- Session regeneration on login to prevent session fixation attacks
- Session key is a 32-byte value auto-generated on first startup and
stored in the database
- Production security headers on all responses: HSTS, X-Content-Type-Options
(`nosniff`), X-Frame-Options (`DENY`), Content-Security-Policy, Referrer-Policy,
and Permissions-Policy
- Request body size limits (1 MB) on all form POST endpoints
- Prometheus metrics behind basic auth
- Static assets embedded in binary (no filesystem access needed at
runtime)
@@ -871,10 +883,18 @@ linted, tested, and compiled.
failures per target, opens after 5 failures (30s cooldown),
half-open probe to test recovery
### Completed: Security Hardening
- [x] Security headers middleware (HSTS, CSP, X-Frame-Options,
X-Content-Type-Options, Referrer-Policy, Permissions-Policy)
([#34](https://git.eeqj.de/sneak/webhooker/issues/34))
- [x] Session regeneration on login to prevent session fixation
([#38](https://git.eeqj.de/sneak/webhooker/issues/38))
- [x] Request body size limits on form endpoints
([#39](https://git.eeqj.de/sneak/webhooker/issues/39))
### Remaining: Core Features
- [ ] Per-webhook rate limiting in the receiver handler
- [ ] Webhook signature verification (GitHub, Stripe formats)
- [ ] Security headers (HSTS, CSP, X-Frame-Options)
- [ ] CSRF protection for forms
- [ ] Session expiration and "remember me"
- [ ] Password change/reset flow