An unverified address claim lives for ever and blocks the real holder from registering it #891

Closed
opened 2026-10-10 17:25:16 +00:00 by tiagoagueda · 0 comments
Owner

#731 stops a reset key, a sign-in code and (with #730) a single sign-on login from reaching an account that only claims an address. The claim itself is still stored for ever, and still has an effect on the person it was made against.

What exists today

  • /accounts/email/ stores any address nobody holds as an unverified EmailAddress on the account that asked, and keeps it until that account removes it; nothing expires it. The page stays reachable with the several-addresses feature switched off (accounts/addresses.is_offered only hides the link).
  • allauth's assess_unique_email (account/internal/flows/manage_email.py) answers a sign-up for such an address with a redirect to the verification page and creates no account. The real holder can never register it, and is told to use the password reset, which (since #731) now mails them no account for this address.

What would change

  • Unverified rows expire after the lifetime of the confirmation key (an errand in the scheduler), so a claim nobody confirms goes away.
  • A sign-up, or a verification, of the same address by somebody else displaces an unverified claim instead of being refused by it.
  • Adding an address asks for the password again (reauthentication), and the view enforces the several-addresses feature switch instead of only hiding the link.
  • A tests/security case: claim an address, then register it as another person.

Decisions

  • How long a claim lives. Recommended: the confirmation key's own lifetime (ACCOUNT_EMAIL_CONFIRMATION_EXPIRE_DAYS, three days).

Found while fixing #731 (checked against main at 8c3d03570 plus that fix).

#731 stops a reset key, a sign-in code and (with #730) a single sign-on login from reaching an account that only *claims* an address. The claim itself is still stored for ever, and still has an effect on the person it was made against. ## What exists today - `/accounts/email/` stores any address nobody holds as an unverified `EmailAddress` on the account that asked, and keeps it until that account removes it; nothing expires it. The page stays reachable with the several-addresses feature switched off (`accounts/addresses.is_offered` only hides the link). - allauth's `assess_unique_email` (`account/internal/flows/manage_email.py`) answers a sign-up for such an address with a redirect to the verification page and creates no account. The real holder can never register it, and is told to use the password reset, which (since #731) now mails them *no account for this address*. ## What would change - Unverified rows expire after the lifetime of the confirmation key (an errand in the scheduler), so a claim nobody confirms goes away. - A sign-up, or a verification, of the same address by somebody else displaces an unverified claim instead of being refused by it. - Adding an address asks for the password again (reauthentication), and the view enforces the several-addresses feature switch instead of only hiding the link. - A `tests/security` case: claim an address, then register it as another person. ## Decisions - **How long a claim lives.** Recommended: the confirmation key's own lifetime (`ACCOUNT_EMAIL_CONFIRMATION_EXPIRE_DAYS`, three days). Found while fixing #731 (checked against `main` at `8c3d03570` plus that fix).
tiagoagueda added this to the 0.6.0 milestone 2026-10-10 17:25:16 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
Postulo/postulo#891
No description provided.