Skip to content

Commit 7f81cb2

Browse files
committed
Networks and Sites: Improve user autocomplete search term handling.
In `wp_ajax_autocomplete_user()`, unslash and sanitize the `term` request parameter before it is passed to `get_users()`. Unslashing fixes searching for an email address containing an apostrophe (valid per `is_email()`), which could previously never match because `wp_magic_quotes()` added a slash which `wpdb::esc_like()` then escaped as a literal. Note that the raw term was already safely handled in the user query, since `WP_User_Query` passes the search term through `wpdb::prepare()`, so this is a hardening and correctness fix rather than a security fix. Additionally, a missing, non-string, or empty term now short-circuits with a `0` response instead of returning an empty array, avoiding a PHP warning and needless user queries. Asterisks are also trimmed from the term given that wildcards are appended to it; a term consisting only of asterisks previously resulted in an empty search which matched all users on the network. Also introduce the `Tests_Ajax_wpAjaxAutocompleteUser` test class covering the Ajax action's search behavior, input handling, and capability checks. Developed in #11530. Follow-up to r19897, r20279. Props rajeshcp, wildworks, westonruter, liaison, gaurangsondagar, vgnavada, saadtajik. Fixes #65051. git-svn-id: https://develop.svn.wordpress.org/trunk@63016 602fd350-edb4-49c9-b593-d223f7449a82
1 parent 5f5d96b commit 7f81cb2

2 files changed

Lines changed: 431 additions & 1 deletion

File tree

‎src/wp-admin/includes/ajax-actions.php‎

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,10 @@ function wp_ajax_oembed_cache() {
285285
* Handles user autocomplete via AJAX.
286286
*
287287
* @since 3.4.0
288+
* @since 7.1.0 The search term is now sanitized, and a missing, non-string,
289+
* or empty term results in a `0` response instead of an empty array.
290+
*
291+
* @return never
288292
*/
289293
function wp_ajax_autocomplete_user() {
290294
if ( ! is_multisite() || ! current_user_can( 'promote_users' ) || wp_is_large_network( 'users' ) ) {
@@ -298,6 +302,20 @@ function wp_ajax_autocomplete_user() {
298302

299303
$return = array();
300304

305+
// Obtain the search term, and short-circuit missing/invalid search term.
306+
if ( ! isset( $_REQUEST['term'] ) || ! is_string( $_REQUEST['term'] ) ) {
307+
wp_die( 0 );
308+
}
309+
/*
310+
* Asterisks are trimmed since wildcards are appended below. Without this, a
311+
* term consisting only of asterisks would result in an empty search that
312+
* matches all users.
313+
*/
314+
$term = trim( sanitize_text_field( wp_unslash( $_REQUEST['term'] ) ), '*' );
315+
if ( '' === $term ) {
316+
wp_die( 0 );
317+
}
318+
301319
/*
302320
* Check the type of request.
303321
* Current allowed values are `add` and `search`.
@@ -342,7 +360,7 @@ function wp_ajax_autocomplete_user() {
342360
$users = get_users(
343361
array(
344362
'blog_id' => false,
345-
'search' => '*' . $_REQUEST['term'] . '*',
363+
'search' => '*' . $term . '*',
346364
'include' => $include_blog_users,
347365
'exclude' => $exclude_blog_users,
348366
'search_columns' => array( 'user_login', 'user_nicename', 'user_email' ),

0 commit comments

Comments
 (0)