Skip to content

fix: don't bypass double_confirm_changes when mailer_autoconfirm is true#2601

Open
shkuls wants to merge 3 commits into
supabase:masterfrom
shkuls:fix/double-confirm-autoconfirm-bypass
Open

fix: don't bypass double_confirm_changes when mailer_autoconfirm is true#2601
shkuls wants to merge 3 commits into
supabase:masterfrom
shkuls:fix/double-confirm-autoconfirm-bypass

Conversation

@shkuls

@shkuls shkuls commented Jun 29, 2026

Copy link
Copy Markdown

Problem

Closes #2600

GOTRUE_MAILER_SECURE_EMAIL_CHANGE_ENABLED=true (double_confirm_changes) is silently bypassed when GOTRUE_MAILER_AUTOCONFIRM=true. The email change commits after a single confirmation instead of requiring both the old and new address to confirm.

Related upstream reports:

Root cause

In emailChangeVerify, the guard that holds the flow at "one confirmed, waiting for the second" is:

if !config.Mailer.Autoconfirm &&
    config.Mailer.SecureEmailChangeEnabled &&
    user.EmailChangeConfirmStatus == zeroConfirmation &&
    user.GetEmail() != "" {

GOTRUE_MAILER_AUTOCONFIRM controls whether new signups require email confirmation. It is completely unrelated to email change confirmation. ANDing it here means any deployment with mailer_autoconfirm=true — including the default self-hosted and local dev configuration — silently disables double_confirm_changes with no warning or error.

Verified locally

Reproduced the bug against v2.186.0 with GOTRUE_MAILER_AUTOCONFIRM=true and GOTRUE_MAILER_SECURE_EMAIL_CHANGE_ENABLED=true:

  • Before fix: email change commits after first verification, second token returns otp_expired
  • After fix: email change holds after first verification, commits only after second token is verified

When GOTRUE_MAILER_AUTOCONFIRM=true, the guard in emailChangeVerify that
holds the flow after the first OTP is verified was skipped entirely due to
the !config.Mailer.Autoconfirm condition. This caused the email change to
commit after a single confirmation regardless of SecureEmailChangeEnabled.

Autoconfirm and SecureEmailChangeEnabled are orthogonal: autoconfirm
applies to signup flows, SecureEmailChangeEnabled applies to email change
flows. Remove !Autoconfirm from the guard so double_confirm_changes works
independently of the autoconfirm setting.

Fixes supabase#2600
@shkuls shkuls requested a review from a team as a code owner June 29, 2026 07:27
shkuls and others added 2 commits June 29, 2026 13:01
…true

Adds a regression test for the bug where SecureEmailChangeEnabled was
silently bypassed when Autoconfirm=true. The test asserts that:
- after verifying the first token, the email has NOT changed and
  EmailChangeConfirmStatus is singleConfirmation
- only after verifying the second token does the email change commit

Covers: supabase#2600
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.

[BUG] double_confirm_changes silently bypassed when mailer_autoconfirm is true.

1 participant