Skip to content

fix(security): mail password resets to the stored admin address - #77

Merged
Rushaway merged 1 commit into
mainfrom
fix/lostpassword-stored-email
Oct 26, 2026
Merged

Rushaway merged 1 commit into
mainfrom
fix/lostpassword-stored-email

Conversation

@Rushaway

@Rushaway Rushaway commented Oct 26, 2026 •

Copy link
Copy Markdown
Member

Cherry-pick of upstream sbpp#1607.

Problem

:prefix_admins.email and .validate use a case- and accent-insensitive collation. A password-reset request for ADMIN@EXAMPLE.TEST (or ádmin@example.test) matched the stored row, and the reset mail, then the new password, went to the address typed in the form instead of the stored one. Anyone who could receive mail at a collation-equal variant could take over the account. The token check also ran through the same collation, so it wasn't byte-exact.

Fix

  • auth.lost_password: select the stored email, roll the token by aid, mail the stored address.
  • ?p=lostpassword: narrow by email in SQL, compare the token with hash_equals, send the new password to the stored address.
  • Mailer::overrideTransportForTests() test seam + new AuthTest coverage.

Fork adaptations

Tests

AuthTest|LostPassword|Mailer: 44 tests OK (sbpp-nide stack). E2E specs not run locally (no mailpit in that stack).

CHANGELOG: 2.2.1-srcdslab.

Cherry-pick of upstream sbpp#1607 (91b69b9).

Send reset mail to the address stored on the admin row, update the
token by aid, and compare the reset token byte-exact with hash_equals.
`:prefix_admins.email` and `.validate` use a case- and accent-
insensitive collation, so a request for `ADMIN@EXAMPLE.TEST` (or an
accent variant) matched the stored row and the reset mail went to the
typed variant instead of the stored address.

Fork adaptations:
- keep `Host::panelUrl()` (#72) for the reset link and home URL;
- the lostpassword E2E seeder keeps the dedicated `lostpw-happy` admin
  as its default (completing a reset revokes the target admin's
  sessions since #63) and gains upstream's per-address argument;
- AuthTest decodes HTML entities in the mail body, since template
  values are HTML-escaped here (#65).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@Rushaway
Rushaway requested review from cmer81 and maxijabase October 26, 2026 07:53
@Rushaway
Rushaway merged commit 8207005 into main Oct 26, 2026
5 checks passed
@Rushaway
Rushaway deleted the fix/lostpassword-stored-email branch October 26, 2026 08:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants