Opened 5 years ago
Last modified 3 weeks ago
#52976 new defect (bug)
user emails comparison should be case insensitive
| Reported by: |
|
Owned by: | |
|---|---|---|---|
| Milestone: | Awaiting Review | Priority: | normal |
| Severity: | normal | Version: | 4.3 |
| Component: | Users | Keywords: | good-first-bug has-patch has-screenshots reporter-feedback |
| Focuses: | Cc: |
Description (last modified by )
In user.php for WordPress 5.7, email update comparisons are case sensitive. Is there a specific reason for this? Because emails are case insensitive. Here is the line that does that:
if ( isset( $userdata['user_email'] ) && $user['user_email'] !== $userdata['user_email'] )
Can the function:
strcasecmp
be used instead? The problem is that there is a plugin that uses the function:
wp_update_user
And it would send a notification for email change even if it was the casing of the characters only.
Thanks for your time and consideration
Attachments (3)
Change History (17)
#2
in reply to:
↑ 1
@
5 years ago
Hello @dd32,
Thanks for your response. The plugin that uses
wp_update_userdoes not alter the casing. It simply passes the email address to it and does not perform any checks on the similarity of the old and new addresses.
Ok, I have seen your note in https://tools.ietf.org/html/rfc5321 now. I am not sure how to take this further, so feel free to close the ticket if you prefer to stick to the RFC.
#3
@
5 years ago
- Description modified (diff)
- Version changed from 5.7 to 4.3
Related: #32158
strcasecmp was used for the wp_insert_user function (but not wp_update_user)
#4
@
5 years ago
- Keywords needs-patch good-first-bug added
Just noting the locations I could find that use != for email comparisons:
wp-includes/user.php: if ( $user_email !== $old_user_data->user_email || $user_pass !== $old_user_data->user_pass ) {
wp-includes/user.php: if ( isset( $userdata['user_email'] ) && $user['user_email'] !== $userdata['user_email'] ) {
wp-admin/user-edit.php: if ( $new_email && $new_email['newemail'] != $current_user->user_email && $profileuser->ID == $current_user->ID ) :
wp-admin/index.php: $hide = ( 0 === $option || ( 2 === $option && wp_get_current_user()->user_email !== get_option( 'admin_email' ) ) );
wp-admin/includes/class-wp-screen.php: if ( 2 === $welcome_checked && wp_get_current_user()->user_email !== get_option( 'admin_email' ) ) {
wp-admin/options-general.php:if ( $new_admin_email && get_option( 'admin_email' ) !== $new_admin_email ) :
And for completeness, those which use strcasecmp():
wp-includes/capabilities.php: if ( $user && 0 !== strcasecmp( $user->user_email, get_site_option( 'admin_email' ) ) ) {
wp-includes/pluggable.php: if ( 0 !== strcasecmp( $user->user_email, get_option( 'admin_email' ) ) ) {
wp-includes/pluggable.php: if ( 0 !== strcasecmp( $user->user_email, get_option( 'admin_email' ) ) ) {
wp-includes/user.php: if ( ( ! $update || ( ! empty( $old_user_data ) && 0 !== strcasecmp( $user_email, $old_user_data->user_email ) ) )
wp-admin/user-edit.php: <?php if ( 0 !== strcasecmp( $profileuser->user_email, get_site_option( 'admin_email' ) ) || ! is_super_admin( $profileuser->ID ) ) : ?>
#5
@
5 years ago
Hi, I found some other locations that use !== and === for emails comparisons.
wp-admin\includes\class-wp-automatic-updater.php:
if ( $notified && get_site_option( 'admin_email' ) === $notified['email'] && $notified['version'] == $item->current ) {
wp-admin\includes\class-wp-automatic-updater.php:
if ( $n && 'fail' === $n['type'] && get_site_option( 'admin_email' ) === $n['email'] && $n['version'] == $core_update->current ) {
wp-admin\includes\misc.php:
if ( get_option( 'admin_email' ) === $value || ! is_email( $value ) ) {
wp-admin\network\settings.php:
if ( $new_admin_email && get_site_option( 'admin_email' ) !== $new_admin_email ) :
wp-includes\ms-functions.php:
if ( get_site_option( 'admin_email' ) === $value || ! is_email( $value ) ) {
Because I'm new to contributing to WordPress, should I create a patch that uses strcasecmp() for email comparisons, or should I wait until it's clear that we need case insensitive email comparison?
#7
@
4 years ago
Hello,
I've updated the initial patch because it wasn't compatible with the latest WP version
This ticket was mentioned in PR #4751 on WordPress/wordpress-develop by @adamsilverstein.
3 years ago
#9
Trac ticket: https://core.trac.wordpress.org/ticket/52976
This ticket was mentioned in PR #9196 on WordPress/wordpress-develop by PANawkar.
7 months ago
#10
Trac ticket:
#11
@
3 weeks ago
I reviewed PR #9196 and the approach using strcasecmp() for case-insensitive email comparisons looks correct. This aligns with how other parts of WordPress Core already handle email comparisons (as noted in comment 4 by @dd32).
The fix properly addresses the issue where users receive unnecessary "email changed" notifications when only the letter casing differs (e.g., User@… vs user@…).
While RFC 5321 technically allows case-sensitive local parts, virtually all mail servers treat emails as case-insensitive. This change improves user experience without breaking compatibility.
+1 for committing this patch. The PR has been open for 7 months and would benefit from a review from a committer.
@showravhasan commented on PR #9196:
3 weeks ago
#12
Reviewed the code changes. The approach using strcasecmp() for case-insensitive email comparisons is correct and consistent with how other parts of WordPress Core already handle email comparisons.
LGTM 👍
Left a comment on the Trac ticket as well: https://core.trac.wordpress.org/ticket/52976
#13
@
3 weeks ago
- Keywords has-screenshots added; needs-testing removed
Reproduction Report
Description
This report validates whether the issue can be reproduced.
Environment
- WordPress: 7.0-alpha-61500
- PHP: 8.3.30
- Server: PHP.wasm
- Database: WP_SQLite_Driver (Server: 8.0.38 / Client: 3.51.0)
- Browser: Chrome 143.0.0.0
- OS: macOS
- Theme: Twenty Twenty-One 2.7
- MU Plugins: None activated
- Plugins:
- Test Reports 1.2.1
Steps to Reproduce
Use playground:
https://playground.wordpress.net/?php=8.3&wp=trunk&networking=yes
Method1 - Manually
- WordPress dashboard > Users > View your user email (e.g. admin@…)
- Click username and change email to ADMIN@…
- Profile updates but no notification is triggered. Email is visible with the uppercase version.
- Change it to a different email such as user@… and notification is triggered.
Method2 - Programmatically
- Install any classic theme
- Add the following code to functions.php
// Get a test user
$user_id = 1;
$user = get_userdata($user_id);
$original_email = $user->user_email; // e.g., "admin@localhost.com"
// Update with same email but different case
$result = wp_update_user([
'ID' => $user_id,
'user_email' => strtoupper($original_email) // "ADMIN@LOCALHOST.COM"
]);
- Visit Users page and check the user email.
- Email is updated but no notification is triggered.
Actual Results
- ❌ Email notification is not triggered with the uppercase version.
Supplemental Artifacts
Method1 - Manually:
Users screen after manually updating the email to uppercase version (notification NOT triggered)

Users screen after manually updating the email to a different email (notification triggered)

Method2 - Programmatically:
Users screen after changing email programmatically (notification NOT triggered)



Hi @asaifm and welcome to Trac!
Updating this to use lower-case comparisons (Just throw it through strtolower() IMHO) seems reasonable, however.. a plugin altering the user email address to lower case does seem unexpected and potentially a bigger bug than this is.
Just as a note,
user@example.comandUSER@example.comcould technically be different users, as the email standard delegates that to the mail servers, however in reality no mail servers that I'm aware of have case sensitive handling..