fix: security & privacy (rate limiter fix, csrf session cookie, logout on server, drafts stale token passw, login timing, password over 72b, JWT_SECRET complexity, SMTP TLS, CSV export neutralised, fonts bundled, upload metadata, hourly cleanup job, privacy.md report)

This commit is contained in:
Florian Sylvain committed 2026-10-22 00:49:19 +02:00
1 parent e2812ee0b9
commit ea98c5ec05
118 files changed
+3828 -130

No files matched your search

@@ -10,7 +10,7 @@ Feature: The rate limiter keys on the real connection address, trusting a forwar
Background:
Given POST /v1/auth/login and POST /v1/auth/password-reset are each wrapped, inside
NewAuthRouter, by a middleware that runs before RateLimiter (api/middleware/rateLimit.go),
which keys its counters on r.RemoteAddr
which keys its counters on the host portion of r.RemoteAddr, never on its source port
And this slice replaces chimiddleware.RealIP on those two route groups with
TrustedProxyRealIP(trustedProxies []string) func(http.Handler) http.Handler
(api/middleware/trustedProxyRealIP.go)
@@ -96,3 +96,23 @@ Feature: The rate limiter keys on the real connection address, trusting a forwar
X-Real-IP header
Then the first response is not rejected by rate limiting and the second is 429 — both are
counted against "10.0.0.1" itself
Scenario: New connections from the same address share one counter
Given TRUSTED_PROXIES is "" and AUTH_RATE_LIMIT_MAX_ATTEMPTS is 1
When a request arrives with connection address "203.0.113.7:40000"
And a second request arrives with connection address "203.0.113.7:40001"
Then the first response is not rejected by rate limiting and the second is 429, because the
counter is keyed on "203.0.113.7" and the source port is ignored
Scenario: A forwarded client keeps one counter across the proxy's connections
Given TRUSTED_PROXIES is "10.0.0.1" and AUTH_RATE_LIMIT_MAX_ATTEMPTS is 1
When a request arrives with connection address "10.0.0.1:51000" and header
X-Real-IP: "198.51.100.9"
And a second request arrives with connection address "10.0.0.1:51001" and the same header
Then the first response is not rejected by rate limiting and the second is 429
Scenario: Expired counters do not accumulate
Given requests from many distinct addresses
When a full window has passed since a counter started
Then the next request evicts every counter whose window has ended, so memory stays bounded by
the addresses seen within one window