WordPress.org

Making WordPress.org

Opened 5 years ago

Closed 3 months ago

Last modified 3 months ago

#77 closed enhancement (maybelater)

Setup two-factor authentication for privileged WordPress accounts

Reported by: iandunn Owned by:
Milestone: Priority: high
Component: Login & Authentication Keywords:
Cc:

Description

All WordPress accounts on the various community sites should be required to pass multiple auth factors when logging in, if they could potentially cause trouble in the event that they were hacked. The existing measures are great, but 2FA would provide an extra layer of protection, without placing an unreasonable burden on users.

Who?
Definitely Admins and Super Admins, but possibly also Editors. Maybe it shouldn't be mandatory for admins on individual WordCamp.org sites, but it should at least be an option.

The SSO adds a couple complicating factors here, though:

  • If there are certain sites where it isn't mandatory, there'd have to be a way to ensure that you couldn't just login to a single-factor site and then browse over to a multi-factor site without passing the additional factor.
  • Similarly, it will also need to account for the fact that users have different roles on different sites. So, someone whose a Subscriber on site A and administrator on site B should be required to pass the second factor when logging into site B, even if they're already logged in from site A.

How?
Google Authenticator and Duo Security are the first two that come to mind, but there may be others that would fit well. Both have existing WP plugins that could potentially be leveraged one way or another.

Another option might be to use WordPress.com Connect. That would mean relying on an external service, though, and we'd need a way to enforce that the targeted users have 2FA enabled on their account.

What else?
What other issues are there that need to be addressed?

Change History (61)

#1 @Otto42
5 years ago

Recently I've found that Duo Security does not have individual user device management capabilities. Meaning that administrator intervention is required for a user to, say, get a new phone and hook up Duo on the new device.

I'll audit the existing Google Authenticator code and see how well it works for this task. The Authenticator system is not centrally managed and thus probably a better fit.

#2 @iandunn
5 years ago

There's also WordPress.com's Google Auth implementation that we could borrow from. Let me know if you want me to send you a copy of it.

One benefit it has over the Google Auth plugin in the repo is that it only prompts for the auth code if the user has 2FA enabled on their account. That's something we'd have to modify the repo plugin to do before we could use it, otherwise users would be confused about what to do with the extra input field.

#3 @Otto42
5 years ago

@iandunn: Sure, email me a copy of that. I've been looking at the plugin in the repo and how we can improve it for generic use all-around, sort of thing.

#4 @iandunn
5 years ago

Cool, there's also a thread for updating the repo plugin so that the prompt is on a second page.

This ticket was mentioned in IRC in #wordpress-meta by sams. View the logs.


4 years ago

#6 @Otto42
4 years ago

This will be easier to do when we get more of the site running similar versions of software. Right now, we're running like 3 different bbPress versions, a couple different WordPress versions, etc. Suggest leaving this off for now until we unify more things.

#7 @samuelsidler
3 years ago

  • Priority changed from normal to high

With the 2FA feature plugin in-progress, we should probably use that.

This ticket was mentioned in Slack in #meta by ocean90. View the logs.


2 years ago

#9 @ocean90
2 years ago

  • Component changed from General to login.wordpress.org
  • Priority changed from high to normal

#10 @dd32
18 months ago

FWIW; This should go ahead even if we can't bring 2FA to SVN access immediately.
Something is better than nothing, and we can iterate on adding either a SVN token or proper 2FA challenges for commits after.

This ticket was mentioned in Slack in #meta by tellyworth. View the logs.


5 months ago

#12 @tellyworth
5 months ago

  • Priority changed from normal to high

#13 @dd32
5 months ago

Remaining questions about implementation that come to my mind:

  • Do we support a way for a user to disable 2FA when they've lost their access?
    • Automated reset-password email style with a time-delay, or do we require that they email the password-resets supportpress?
  • Do we want to support backup codes? How should they work?
    • Should a backup code be treated the same as logging in normally with a 2FA device or is it more limited?
  • Where do users manage the 2FA process?
    • Personally I think this is a good time to introduce login.wordpress.org/my-account where we can have this kind of thing (and future account-related stuff). That would allow a future profiles.wordpress.org to be a read-only service which would simplify things a bit.
  • How does WordCamp.org/BuddyPress.org/bbPress.org/SVN fit into this?
    • IMHO the other *.org properties should be updated to login through login.wordpress.org with a SSO redirect back to the property.
    • SVN access, other HTTP Basic Auth, Trac XML-RPC, etc. would bypass 2FA requirements initially, with future iterations to find a solution there
      • SVN: svn+ssh is the only way to do a 2FA challenge
      • Alternatively, application-passwords also fit this purpose.

#14 @dd32
4 months ago

In 6734:

2FA: Add the wporg-two-factor plugin folder.

(this page intentionally left blank)

See #77.

#15 @dd32
4 months ago

In 6735:

2FA: Add an initial wporg-two-factor plugin to exted and customise the two-factor plugin for WordPress.org usage.

See #77.

#16 @Otto42
4 months ago

SVN: svn+ssh is the only way to do a 2FA challenge
Alternatively, application-passwords also fit this purpose.

What do we use currently to connect the SVN authentication to the WordPress database? I believe that it is something custom?

Edit: nm, found it.

Last edited 4 months ago by Otto42 (previous) (diff)

#17 @obenland
4 months ago

In 6736:

2FA: Activate plugins on wporg sandboxes.

See #77.

#18 follow-up: @Otto42
4 months ago

Reading through the various options and ways to do 2FA with SVN, it seems to me that a form of application passwords is the only way to go. What with so many tools being scripted and automated methods for people to do svn operations, if we want to avoid breaking anything, then using something like application passwords is the only way to do the job.

I'd go so far as to suggest that we generate these application passwords ourselves and provide the users with a method to regenerate them, but not to actually set them manually. This way we can ensure that the passwords are long enough to be secure. An interface would need to exist to provide the button to regenerate them.

For SVN in particular, we would need to modify the forked *_auth_mysql library currently in use, or we'd need to change the queries that it uses so it can find this new svn-specific password and use that.

For security, the app password should only work with the particular use case (SVN password only works with SVN, you can't log in with it on the website) and the app in question should start only using that app-specific password (you can no longer use your website password for SVN commits). These restrictions would only be in place when 2FA is enabled for that specific account.

#19 in reply to: ↑ 18 @dd32
4 months ago

Replying to Otto42:

Reading through the various options and ways to do 2FA with SVN, it seems to me that a form of application passwords is the only way to go.

Yeah, I've looked through everything, and unless we were to use svn+ssh:// there's no real good way other than Application passwords.

FYI, our initial intention is that 2FA won't apply to SVN and other locations we use Basic auth - that's due to these requiring further development around how we actually authenticate it.

I'd go so far as to suggest that we generate these application passwords ourselves and provide the users with a method to regenerate them, but not to actually set them manually. This way we can ensure that the passwords are long enough to be secure. An interface would need to exist to provide the button to regenerate them.

Application Passwords should never be generated by an end-user. The application-password plugin in use on w.org presently (make/hosting for the test reporters) generates okay passwords but could be better.
I'd also like to extend it to allow us to specify the 'type' of password (This is only for SVN, This is only for XML-RPC, etc).

For SVN in particular, we would need to modify the forked *_auth_mysql library currently in use, or we'd need to change the queries that it uses so it can find this new svn-specific password and use that.

Correct. I haven't discussed this with Systems yet, however I'm thinking that using a Subrequest module for auth would be best, for example nginx has http://nginx.org/en/docs/http/ngx_http_auth_request_module.html - It'd allow us to move the Authentication for SVN into PHP and just use WordPress function calls. Theres a few Apache module choices there, but those implementation details need to be discussed with Systems directly.
It'll also allow us to store/use the "Last time this password was used" functionality.

Last edited 4 months ago by dd32 (previous) (diff)

#20 @obenland
4 months ago

In 6737:

2FA: First pass at new user edit UI.

Needs more work around changing devices, backup codes, and (possibly) application passwords.

See #77.

#21 @tellyworth
4 months ago

In 6738:

2FA: import a copy of class.two-factor-core.php from upstream trunk.

Needed so we can make it extendable and override some functions.

See #77

#22 @obenland
4 months ago

In 6740:

2FA: First pass at adding backup codes.

See #77.

#23 @obenland
4 months ago

In 6747:

2FA: Second pass at backup codes

Now copies/prints/downloads codes.
Also added links to authentication apps.

See #77.

#24 @dd32
4 months ago

In 6748:

2FA: WPORG_Two_Factor now extends Two_Factor_Core so that we can override some of the larger surface methods.

This is being done to allow us to customise how some functionality of the plugin works.

See #77.

#25 @obenland
4 months ago

In 6749:

2FA: Avoid double error messages.

See #77.

#26 @dd32
4 months ago

In 6753:

2FA: Add a single method to enable/disable 2FA for a user.

This introduces a abstract Primary and Secondary provider class to allow us to alter how these providers handle generation behind the scenes.

See #77.

#27 @tellyworth
4 months ago

In 6757:

2FA: make sure ajaxurl is available, not just for debug bar users.

See #77

#28 @tellyworth
4 months ago

In 6758:

2FA: fix issue with inconsistent usermeta. See #77

#29 @dd32
4 months ago

In 6759:

2FA: Enable Email, Slack, and Backup Codes as the backup 2FA method.

See #77.

#30 @dd32
4 months ago

In 6760:

2FA: Fix a typo in r6759

See #77

#31 @dd32
4 months ago

In 6761:

2FA: Have WPORG_Two_Factor_Email be it's own provider in it's own right.

By extending WPORG_Two_Factor_Email for WPORG_Two_Factor_Slack it was found that Two_Factor_Email uses self:: a bunch causing the usermeta token override not to take effect.

See #77.

#32 @tellyworth
4 months ago

In 6762:

2FA: simple style to highlight authcode form when input is invalid.

See #77

#33 @tellyworth
4 months ago

In 6763:

2FA: move inline css to external file.

Also improve client-side input validation.

See #77

#34 @obenland
4 months ago

In 6775:

2FA: Limit UI to caped users.

See #77.

#35 @tellyworth
4 months ago

In 6780:

2FA: add a constant to easily disable the two factor plugin if something goes wrong.

See #77

#36 @dd32
4 months ago

In 6781:

2FA: Switch from using a nonced login to defining a wporg_2fa cookie instead.

This works by making the WordPress cookies only valid when the 2FA cookie is also set.
This differs from the two-factoe plugin which only sets auth cookies after 2FA is completed.

See #77.

#37 @obenland
4 months ago

In 6782:

2FA Make login markup and styles blend in better

See #77.

#38 @dd32
4 months ago

In 6783:

2FA: Remove uneeded function from r6782.

See #77.

#39 @dd32
4 months ago

In 6784:

2FA: Always send the email/slack tokens to users upon first load of the backup methods.

See #77.

#40 @obenland
4 months ago

In 6785:

2FA: Move resend button below the form

Fixes a bug where codes wouldn't be submitted correctly and improves flow.

See #77.

#41 @dd32
4 months ago

In 6786:

2FA: enable_two_factor() and disable_two_factor() shouldn't be static.

See #77.

#42 @dd32
4 months ago

In 6787:

2FA: Remove reminents of wp-auth-nonce.

See #77.

#43 @dd32
4 months ago

In 6788:

2FA: Always show the "Try a backup option" link when using the primary authentication class.

See #77.

#44 @tellyworth
4 months ago

In 6789:

2FA: remove enqueue style. See #77

#45 @dd32
4 months ago

In 6790:

2FA: Remove Provider translations as they're not actually used for display anywhere. Replace with static strings.

See #77.

#46 @obenland
4 months ago

In 6791:

2FA: Don't use submit and cancel buttons.

See #77.

#47 @tellyworth
4 months ago

Some things that aren't yet done, that would need to be complete for a full public release:

  • Require a code to disable 2FA
  • Better superadmin view when editing users (disable-only)
  • Expire email and Slack backup codes
  • Add support for Trac and other w.org properties

#48 @dd32
4 months ago

In 6792:

2FA: Remove the sandbox requirement from 2FA. This is now launched for a subset of users.

See https://make.wordpress.org/meta/2018/02/27/two-factor-authentication-on-wp-org/
See #77.

#49 @obenland
4 months ago

In 6793:

2FA: Broaden access to all users with watched pwds.

See https://wordpress.slack.com/archives/C18723MQ8/p1519703782000085
See #77.

#50 @ocean90
4 months ago

Getting Notice: Undefined index: action in wporg-two-factor/wporg-two-factor.php on line 80 when I reload the page that asks me for the authentication code.

#51 @obenland
4 months ago

In 6794:

2FA: Be clearer about the kind of mobile app needed

Props _dorsvenabili.
See #77.

#52 @dd32
4 months ago

In 6795:

2FA: Fix a PHP notice during login where $_GET['action'] is not set.

H/T ocean90.
See #77.

#53 @dd32
4 months ago

In 6796:

2FA: Run capital_P_dangit() over the plugin.

H/t swissspidy.
See #77.

This ticket was mentioned in Slack in #core-committers by iandunn. View the logs.


4 months ago

#55 @dd32
4 months ago

In 6799:

2FA: Re-set the 2FA cookie when authentication cookies are re-set while logged in (ie. Password Change).

See #77.

This ticket was mentioned in Slack in #core by jeffpaul. View the logs.


4 months ago

#57 @obenland
4 months ago

In 6812:

2FA: Replace jQuery handlers with React client.

This does not aspire to be the end all be all of React clients, but it's an improvement over the existing one.
Can probably use a good amount of refinement and optimization.

See #77.

#58 @tellyworth
3 months ago

In 6843:

2FA: disable the two-factor test.

See #77

#59 @tellyworth
3 months ago

  • Resolution set to maybelater
  • Status changed from new to closed

This needs further work at some point in the future, when it can be properly integrated with Subversion and other services. Closing it as maybelater until we have the resources to do that.

#60 @ocean90
3 months ago

#3498 was marked as a duplicate.

#61 @pento
3 months ago

A side note to this: I've been chatting to Authy folks, there's no possibility of the WordPress logo being added to the Authy apps, they're not adding new TOTP logos to the apps anymore.

Note: See TracTickets for help on using tickets.