From 06a7bfb2b96086ea974469c98d9bcd4a5ab2de75 Mon Sep 17 00:00:00 2001 From: Anna Larch Date: Mon, 6 Jul 2026 15:26:39 +0200 Subject: [PATCH] fix(settings): trust reverse proxy for client IP in rate limiting Apache/mod_wsgi logs show every request's remote address as 127.0.0.1, meaning a reverse proxy sits in front of it. allauth's rate limiter (used by ACCOUNT_RATE_LIMITS["login_failed"]) only reads the real client IP from X-Forwarded-For when ALLAUTH_TRUSTED_PROXY_COUNT > 0; left unset, it fell back to REMOTE_ADDR, i.e. the proxy's own address for every visitor. That collapsed the per-IP login_failed limit into a single site-wide bucket of 10 failed attempts per hour shared by every user, so once exhausted (typos, scanners, credential stuffing), regular username/password login was rejected for everyone until the hour rolled over -- while GitHub OAuth, a separate code path with no rate limiter, kept working. This matches reports of 'GitHub login works but regular login doesn't'. Set ALLAUTH_TRUSTED_PROXY_COUNT = 1 so allauth resolves the real client IP from the last hop of X-Forwarded-For instead of REMOTE_ADDR, restoring per-visitor rate limiting. Pending sysadmin confirmation that there is exactly one reverse proxy hop in front of Apache, that it sets X-Forwarded-For itself (rather than forwarding a client-supplied value), and that Apache is never reachable bypassing that proxy -- required for this setting to be safe. Signed-off-by: Anna Larch --- CHANGELOG.md | 4 ++++ nextcloudappstore/settings/base.py | 6 ++++++ 2 files changed, 10 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 36d126e2ac7..08883f48134 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,10 @@ ## [Unreleased] +### Fixed + +- Trust the reverse proxy's `X-Forwarded-For` header for login rate limiting, so failed-login limits apply per visitor instead of collapsing into a single site-wide bucket. + ## [4.11.3] - 2026-01-05 ### Changed diff --git a/nextcloudappstore/settings/base.py b/nextcloudappstore/settings/base.py index fcf913d62f6..e622d190170 100644 --- a/nextcloudappstore/settings/base.py +++ b/nextcloudappstore/settings/base.py @@ -139,6 +139,12 @@ "manage_email": "3/h/user", } +# We run behind a single reverse proxy, which sets X-Forwarded-For. Without +# this, allauth's rate limiting (e.g. ACCOUNT_RATE_LIMITS["login_failed"] +# above) falls back to REMOTE_ADDR, which is the proxy's own address for +# every request -- collapsing per-IP limits into a single site-wide bucket. +ALLAUTH_TRUSTED_PROXY_COUNT = 1 + SITE_ID = 1 # Allauth configuration