Count an IPv4-mapped login client by its IPv4 address (closes #66)
check / check (push) Successful in 2m33s
check / check (push) Successful in 2m33s
A proxy on a dual-stack listener forwards an IPv4 client as ::ffff:a.b.c.d, whose /64 is the same for every IPv4 client, so one client's failed logins refused everyone's. The rate limit key now unmaps the address first. README.md now says that with the default trusted_proxies a client with a private address can choose its counted address through X-Forwarded-For, and that setting trusted_proxies to the proxy's own address closes this. Model: opus-5-5
This commit is contained in:
@@ -33,11 +33,12 @@ exhaustion
|
||||
- 2026-09-28 rate limit the login form (closes #66): `POST /` is limited to 5
|
||||
attempts per minute per client address, and an attempt over the limit is
|
||||
refused with 429 and a `Retry-After` header; the address is the one
|
||||
`internal/clientip` resolves through `trusted_proxies`, and an IPv6 client is
|
||||
counted by its /64; the limit is a `RateLimit` middleware in
|
||||
`internal/middleware` on `github.com/go-chi/httprate`, which the image routes
|
||||
can reuse; the library keeps counts for the current and the previous minute
|
||||
only; documented in `README.md`.
|
||||
`internal/clientip` resolves through `trusted_proxies`, an IPv6 client is
|
||||
counted by its /64, and an IPv4-mapped address as the IPv4 address it
|
||||
carries; the limit is a `RateLimit` middleware in `internal/middleware` on
|
||||
`github.com/go-chi/httprate`, which the image routes can reuse; the library
|
||||
keeps counts for the current and the previous minute only; documented in
|
||||
`README.md`.
|
||||
- 2026-09-28 refuse an unparseable `exp` on `/v1/image/` and log swallowed
|
||||
cache errors (closes #72): an `exp` in the URL that is not a whole
|
||||
number, an empty `exp=` included, is a 400 naming `exp` and the value,
|
||||
|
||||
Reference in New Issue
Block a user