Opened 6 years ago
Last modified 5 years ago
#44094 reviewing enhancement
Hook for WP_User data hydration to enable strong data security
Reported by: | yguez | Owned by: | SergeyBiryukov |
---|---|---|---|
Milestone: | Awaiting Review | Priority: | normal |
Severity: | normal | Version: | |
Component: | Users | Keywords: | has-patch 2nd-opinion |
Focuses: | Cc: |
Description
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 wp_dropdown_users
.
This approach works but has some major downsides:
- The
edit_user_{{$field}}
anduser_{{$field}}
filters are only fired when$user->filter
is truthy (See line 308 ofclass-wp-user.php
). I do my best to ensure that this value is set, but plenty of plugins interact withWP_User
objects without setting theirfilter
property. This results in some plugins outputing encrypted text for fields such asdisplay_name
. - The
edit_user_{{$field}}
anduser_{{$field}}
filters are fired in thesanitize_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 forthe_author
andwp_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:
<?php 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!
Attachments (4)
Change History (18)
This ticket was mentioned in Slack in #gdpr-compliance by yaronguez. View the logs.
6 years ago
This ticket was mentioned in Slack in #core by yaronguez. View the logs.
6 years ago
#4
@
6 years ago
Thanks for all of the detail @yguez. I don't have an opinion about the filter's name—others can weight in on that—but one thing that will be needed before committing is inline documetation: https://make.wordpress.org/core/handbook/best-practices/inline-documentation-standards/php/#4-hooks-actions-and-filters
This ticket was mentioned in Slack in #core by yaronguez. View the logs.
6 years ago
This ticket was mentioned in Slack in #core by yaronguez. View the logs.
6 years ago
#9
@
6 years ago
- Milestone changed from 5.0 to 4.9.9
- Owner set to SergeyBiryukov
- Status changed from new to reviewing
#12
@
6 years ago
- Milestone changed from 5.2 to 5.3
This ticket has not received any attention during the 5.2 cycle. With beta 1 tomorrow, going to punt this to 5.3.
This ticket was mentioned in Slack in #core by david.baumwald. View the logs.
5 years ago
#14
@
5 years ago
- Keywords 2nd-opinion added
- Milestone changed from 5.3 to Awaiting Review
This change looks fine but I think the WordPress project needs to consider a unified approach to filtering the hydration of all object types, not just WP_User
.
Does this pattern make sense to apply to posts, comments, and terms too? If so, this should be tackled in a holistic manner.
Does this introduce the ability for a WP_User
object to contain completely the wrong data compared to what's expected? If so, the implications need consideration.
patch as described by @yguez