[wp-trac] [WordPress Trac] #46130: Only pause extensions for users with recovery access

WordPress Trac noreply at wordpress.org
Mon Jan 28 21:34:14 UTC 2019


#46130: Only pause extensions for users with recovery access
--------------------------+------------------------------------------------
 Reporter:  flixos90      |      Owner:  TimothyBlynJacobs
     Type:  defect (bug)  |     Status:  assigned
 Priority:  highest omg   |  Milestone:  5.1
  bbq                     |
Component:                |    Version:  trunk
  Bootstrap/Load          |
 Severity:  normal        |   Keywords:  needs-patch servehappy 2nd-opinion
  Focuses:                |
--------------------------+------------------------------------------------
 After introduction of the fatal error recovery mechanism in #44458,
 several follow-up tickets were opened. While some were regarding regular
 bugs, quite a few included security concerns, particularly about how a
 malicious attack could cause even safe plugins and themes to be paused.
 Security researchers outside of the WordPress space have already published
 about the problems as well: https://medium.com/websec/wordpress-serve-
 happy-ffd93c94f5ac

 While we have since investigated reducing the attack vectors by pausing
 extensions less aggressively (see #45888, #45940, #46066), it appears that
 it is impossible to reliably prevent all loopholes there.

 In today's PHP meeting, an alternative approach came up:

 * Instead of pausing extensions globally on certain protected endpoints,
 extensions should only be paused for specific users.
 * An admin user could receive a "recovery link" with a secret code, for
 example with an email.
 * When opening the recovery link, the secret code is verified, and then a
 "recovery cookie" is stored on the user's machine, containing a nonce.
 * Whenever such a recovery cookie is present and valid, extension pausing
 is enabled.

 This approach allows reusing most logic that is already in place. Instead
 of pausing on protected endpoints, pausing will happen whenever the cookie
 is present, in any area. In other words, the protected endpoint logic can
 be removed and instead be replaced by the recovery mode check.

 More concrete suggestions regarding the implementation:
 * To generate a new recovery link, use something like
 `wp_generate_password( 20, false )`, and store a hashed version of that
 value as `recovery_key` in the `wp_user_meta` table. Include the raw value
 in the recovery link as a query parameter to be given to the user.
 * When a user clicks the link, check the query parameter. Hash it in the
 same process, then query the user by that `recovery_key` meta value. If no
 user is found, the recovery key is invalid. If one is found, delete the
 key so that it is no longer valid and set a cookie on the device. The
 cookie should use some of the `*_KEY` constants from `wp-config.php` to
 have an unpredictable name.
 * After setting the cookie and deleting the recovery key, the user should
 be redirected to the admin. At this point, the cookie is already placed,
 so recovery mode is de-facto active.
 * Introduce `wp_is_recovery_mode()` or similar. This function should check
 if the cookie exists and is valid. We can then replace all checks for
 `is_protected_endpoint()` with checks for this new function.

 Considerations:
 * What should we store in the cookie? Should the existence of the cookie
 limited to a few minutes/hours/days? Should there be a nonce in the cookie
 value (that itself restricts duration already)?
 * How would an administrator get a recovery link? Should the fatal error
 handler send an email when it detects an error? Should there be an area in
 the admin where a user can request one that is then displayed to them just
 once so that they can copy/paste it?

 We need to find a good measure here that is both secure but also stable
 enough for users. For example consider that, when a site is broken and
 nobody has a valid recovery link, the site is still as inaccessible as
 before, so that should be mitigated.

-- 
Ticket URL: <https://core.trac.wordpress.org/ticket/46130>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform


More information about the wp-trac mailing list