auth: reset links pause for a day after five (audit A3)

Security audit 2026-10-17, finding A3 (low), stage 3. sendReset spaced
reset mails ten minutes apart and capped them at five an hour per account,
so a stranger who repeated a username kept a live 30-minute link arriving
in the administrator's mailbox five times an hour, for ever.

Now five reset links a day per account (resetDayLimiter); the sixth
request sends one notice instead - "Reset links paused for a day", no
link, saying further requests are ignored for 24 hours and that a global
administrator can set a password on Server > Users - and every later one
in the window sends nothing (resetNoticeLimiter), logged either way. In
memory, like every limiter: a restart clears them.

Test: TestResetLinksPauseForADayAfterFive. Docs: security.md, guide §
Account; CHANGELOG; plan.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
mix
2026-10-17 22:15:50 +03:00
co-authored by Claude Opus 5.5
parent 4433688500
commit 8aad5b6223
7 changed files with 78 additions and 6 deletions
+2 -1
View File
@@ -605,7 +605,8 @@ Notifications go to the address either way. Only a confirmed address can be
sent a reset link: *Forgot your password?* on the sign-in page asks for the
username and always answers the same - whether the name exists, and whether
its address is confirmed, is not said; another link is not sent within ten
minutes of the last - and the link
minutes of the last, and after five in a day the owner is mailed once that
further requests are ignored for 24 hours - and the link
(`https://<SELFPOST_HOSTNAME>/login/reset/…`) works once, for 30 minutes, and
only while the account's address is still the one it was sent to. Setting the
new password signs every session of the account out. The links name the
+2 -1
View File
@@ -787,8 +787,9 @@ the argument.
key. — **Sonnet**, 0.5 h. *Done 2026-10-17* (`refusalLog`).
- [x] **A9.** IPv6 keyed by /64. — **Sonnet**, 0.5 h. *Done 2026-10-17:*
TestIPv6IsLimitedPerSlash64.
- [ ] **A3.** After five unsolicited reset links in a day, one mail saying
- [x] **A3.** After five unsolicited reset links in a day, one mail saying
further requests are ignored for 24 h, then silence. — **Opus**, 1.5 h.
*Done 2026-10-17:* TestResetLinksPauseForADayAfterFive.
- [ ] **I6.** `/healthz` answered only to loopback and trusted-proxy peers;
the guide's "Container health" says the proxy may expose it on purpose
with the fragment line. — **Sonnet**, 0.5 h.
+4 -1
View File
@@ -176,7 +176,10 @@ The panel is exposed to the internet — the items below are **not optional**.
after answering, so neither the words nor the time tell whether a name
exists or is confirmed; requests are limited to five in 15 minutes per
client address and username (fifty per address alone), mails to five an
hour per account, and a link's page to 30 requests in 15 minutes per link
hour per account and five reset links a day - after which the owner is
told once that further requests are ignored for 24 hours, and nothing
more is sent (`2.14.4`; audit A3: anyone who knew a username kept a live
link in that mailbox five times an hour) - and a link's page to 30 requests in 15 minutes per link
(300 per address alone), so one stranger behind a shared proxy cannot stop
the others asking for or opening a link (`2.14.4`; audit A1). A link's page changes nothing
on `GET` (a mail scanner opens links): the button does. Setting a password