No limit on wrong passwords for one name or address #409

Closed
opened 2026-11-06 20:10:29 -08:00 by rays · 2 comments
Owner

POST /api/login answers every wrong password 401 for as long as someone keeps trying: nothing counts failures per name or per address. auth::check_password caps how many checks run at once (CHECKS), which keeps a flood from starving the server (#324, the signin load test), but not how many guesses one attacker gets. Found while writing #399, whose list assumed a 429 (too_many) that only icon picks use. A limit per address needs the client's address, and behind Caddy every request comes from 192.168.64.10, so it would have to come from a header Caddy sets and ipx trusts only from Caddy, as Cf-Access-* are; a limit per name does not, but lets anyone lock someone out.

POST /api/login answers every wrong password 401 for as long as someone keeps trying: nothing counts failures per name or per address. auth::check_password caps how many checks run at once (CHECKS), which keeps a flood from starving the server (#324, the signin load test), but not how many guesses one attacker gets. Found while writing #399, whose list assumed a 429 (too_many) that only icon picks use. A limit per address needs the client's address, and behind Caddy every request comes from 192.168.64.10, so it would have to come from a header Caddy sets and ipx trusts only from Caddy, as Cf-Access-* are; a limit per name does not, but lets anyone lock someone out.
rays added the enhancement label 2026-11-06 20:10:29 -08:00
Author
Owner

Left open for a decision: a limit per address needs the client's address, which behind Caddy is 192.168.64.10 for everyone, so it would have to come from a header Caddy sets (X-Forwarded-For) trusted only from Caddy; a limit per name needs none of that but lets anyone lock a person out by guessing wrong for them. Which, or both, is the owner's call.

Left open for a decision: a limit per address needs the client's address, which behind Caddy is 192.168.64.10 for everyone, so it would have to come from a header Caddy sets (X-Forwarded-For) trusted only from Caddy; a limit per name needs none of that but lets anyone lock a person out by guessing wrong for them. Which, or both, is the owner's call.
Author
Owner

Fixed in 8acf579, per address as decided. Ten wrong passwords from one address in a quarter hour hold it off sign-in for the rest of that window: 429, "too many wrong passwords; try again in N minutes". A right password does not reset the count, so an account of one's own cannot clear it. ipx takes the address from the last entry of X-Forwarded-For only when the peer is in trusted_proxies, and otherwise from the peer. Caddy now sets X-Forwarded-For to {client_ip}: Cf-Connecting-IP for the tunnel's requests, believed only from TUNNEL_PEER, and the peer for everyone else, replacing whatever the client sent. Checked with Caddy against an echo upstream, and in production: a sign-in from Tower carrying a forged X-Forwarded-For was logged from=192.168.1.130. The sign-in load test now sends each attempt from its own address. Deployed in ipx 1.5.2-dev and ipx-web.

Fixed in 8acf579, per address as decided. Ten wrong passwords from one address in a quarter hour hold it off sign-in for the rest of that window: 429, "too many wrong passwords; try again in N minutes". A right password does not reset the count, so an account of one's own cannot clear it. ipx takes the address from the last entry of X-Forwarded-For only when the peer is in trusted_proxies, and otherwise from the peer. Caddy now sets X-Forwarded-For to {client_ip}: Cf-Connecting-IP for the tunnel's requests, believed only from TUNNEL_PEER, and the peer for everyone else, replacing whatever the client sent. Checked with Caddy against an echo upstream, and in production: a sign-in from Tower carrying a forged X-Forwarded-For was logged from=192.168.1.130. The sign-in load test now sends each attempt from its own address. Deployed in ipx 1.5.2-dev and ipx-web.
rays closed this issue 2026-11-07 05:21:21 -08:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: rays/ipx#409