[wp-trac] [WordPress Trac] #44094: Hook for WP_User data hydration to enable strong data security

WordPress Trac noreply at wordpress.org
Tue May 15 17:54:31 UTC 2018

#44094: Hook for WP_User data hydration to enable strong data security
 Reporter:  yguez        |      Owner:  (none)
     Type:  enhancement  |     Status:  new
 Priority:  normal       |  Milestone:  Awaiting Review
Component:  Users        |    Version:
 Severity:  normal       |   Keywords:
  Focuses:               |
 Hi there! I'm one of the founders of Crypteron, a data-security platform
 for developers. I'm also active in the WordPress community, an organizer
 of the [San Diego Advanced WordPress Meetup](https://www.meetup.com
 /Advanced-WordPress), an admin of the [Advanced WordPress Facebook
 Group](https://www.facebook.com/groups/advancedwp) (with over 30,000
 members) and a past speaker and organizer at WordCamp San Diego.

 For the past 8 months I've been working on a free plugin called
 **EncryptWP** that brings military-grade data-security to WordPress. It
 automatically encrypts and decrypts sensitive user data such as names,
 email addresses and physical addresses and even supports secure,
 searchable encryption. It's been a labor of love and is available for beta
 testing at https://github.com/crypteron/encryptwp.

 The reason I'm posting a ticket here is that I've had to resort to a non-
 ideal approach to automatic decryption of native (non-meta) user fields
 within WordPress. Ideally I would decrypt sensitive user data right after
 it's loaded from the database as it is hydrated into the `WP_User` object.
 Unfortunately, no hook is fired during this process. I strongly believe
 that one should be.

 Instead, I decrypt native user fields using a combination of the filters:
 `edit_user_{{$field}}`, `{{user_{{$field}}`, `the_author`, and

 This approach works but has some major downsides:
 * The `edit_user_{{$field}}` and `user_{{$field}}` filters are only fired
 when `$user->filter` is truthy (See line 308 of `class-wp-user.php`). I do
 my best to ensure that this value is set, but plenty of plugins interact
 with `WP_User` objects without setting their `filter` property. This
 results in some plugins outputing encrypted text for fields such as
 * The `edit_user_{{$field}}` and `user_{{$field}}` filters are fired in
 the `sanitize_user_field` method which, fundamentally, is not a logical
 place for this sort of operation.
 * Some native WordPress code bypasses the `sanitize_user_field` method so
 I've had to add additional filters for `the_author` and
 `wp_dropdown_users` (using a RegEx!)
 * Rather than decrypting all sensitive data once, I have to decrypt it
 every time it is fetched which is inefficient.

 Despite all of this, EncryptWP works very well. I think the plugin can be
 a game-changer for WordPress, making HIPAA compliant WordPress sites
 possible not to mention the new world of GDPR compliance. We have an
 ambitious, technical road map for the plugin including extending it to
 handle user-defined meta keys, encrypting `wp_post` and `wp_options` data,
 key management, and more. But I'd really love to get it 100% compatible
 and performant with all plugins and, in order to do that, we really need a
 `WP_User` hydration filter.

 Such a filter could benefit many other plugins as well and is guaranteed
 to be backward compatible with all other sites since it would not change
 existing behavior. I would envision that the filter could be added within
 the [WP_User->init](https://github.com/WordPress/WordPress/blob/master/wp-
 includes/class-wp-user.php#L170) method:
 public function init( $data, $site_id = '' ) {
     $this->data = apply_filters('init_user_data', $data, $site_id);
     $this->ID   = (int) $data->ID;
     $this->for_site( $site_id );

 Please let me know your thoughts on adding this new filter. One line of
 code can make all the difference!

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

More information about the wp-trac mailing list