Skip to content

add wp-config support to disable 2fa for a user#908

Open
masteradhoc wants to merge 1 commit into
WordPress:masterfrom
masteradhoc:621-support-wpconfig-entry
Open

add wp-config support to disable 2fa for a user#908
masteradhoc wants to merge 1 commit into
WordPress:masterfrom
masteradhoc:621-support-wpconfig-entry

Conversation

@masteradhoc

Copy link
Copy Markdown
Collaborator

What?

Adds a TWO_FACTOR_DISABLE_FOR_USER wp-config constant that disables the two-factor login challenge for one or more named users, so an operator with filesystem access can recover a locked-out account without database surgery or a second admin.

Fixes # TBD

Why?

When a user loses their second factor and the site has no other administrator, today's only operator options are editing the database directly or un-checking options as a second admin. There is no supported wp-config.php lever to bypass 2FA for a single account.

This implements a per-user wp-config constant to improve the account recovery possibilities. Crucially, it is per-user, not site-wide, because disabling 2FA for everyone just because one person is locked out throws away the protection of every other account. Because the constant lives in wp-config.php (filesystem access only), it carries the same trust level as shell/DB access and adds no new attack surface.

Related discussion:

How?

Two small functions in two-factor.php, registered in two_factor_register_admin_hooks():

  • two_factor_bypass_primary_provider_for_user() hooks the existing two_factor_primary_provider_for_user filter. For a matching user it returns null, which makes Two_Factor_Core::is_user_using_two_factor() report false so wp_login() lets the user through without a second factor.
    • This hook point is deliberate: it runs after core's fail-closed logic, so it does not trip the fallback that would otherwise force-enable emailed codes (which is what would happen if the enabled/supported providers were emptied instead).
    • The matched user is loaded once with get_userdata() and compared by ID, login, or email. The constant accepts a single identifier, a comma-separated list, or an array.
  • two_factor_bypass_admin_notice() shows a standing admin_notices warning (to manage_options users) whenever the constant is set, echoing the configured value so a forgotten bypass — or a typo — is easy to spot.

Usage in wp-config.php:

define( 'TWO_FACTOR_DISABLE_FOR_USER', 'admin' );                       // one user
define( 'TWO_FACTOR_DISABLE_FOR_USER', 'admin, secondadmin' );            // CSV list
define( 'TWO_FACTOR_DISABLE_FOR_USER', array( 'admin', 'secondadmin' ) ); // array

Use of AI Tools

AI assistance: Yes
Tool(s): Claude Code
Model(s): Claude Opus 4.8
Used for: Drafting the implementation and PR text. The hook choice, scope decision (per-user, no global switch), and final code were reviewed and edited by me.

Testing Instructions

  1. Pick a user who has 2FA enabled (e.g. admin) and confirm they normally get the second-factor prompt at login.
  2. Add define( 'TWO_FACTOR_DISABLE_FOR_USER', 'admin' ); to wp-config.php, then log out and log in as admin with password only — confirm no 2FA prompt.
  3. Log in as a different 2FA user not named in the constant — confirm they still get the 2FA prompt.
  4. Repeat step 2 using each identifier form (user ID, email, and a comma-separated list of two users) — confirm the bypass applies in each case.
  5. With the constant set, open any wp-admin page as an administrator — confirm the yellow warning notice appears showing the configured value.
  6. Remove the constant, log out and back in as admin — confirm the 2FA prompt returns and the notice is gone.
  7. Negative: set the constant to a non-existent identifier (e.g. 'nobody') — confirm no user is bypassed and real 2FA users are still challenged.

Screenshots or screencast

image

Changelog Entry

Added - TWO_FACTOR_DISABLE_FOR_USER wp-config constant to bypass two-factor for one or more named users (by ID, login, or email) for account recovery, with an admin notice while a bypass is active.

@masteradhoc masteradhoc added this to the 0.17.0 milestone Jun 14, 2026
@masteradhoc masteradhoc self-assigned this Jun 14, 2026
@github-actions

Copy link
Copy Markdown

The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the props-bot label.

If you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message.

Co-authored-by: masteradhoc <masteradhoc@git.wordpress.org>

To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook.

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.

1 participant