[wp-trac] [WordPress Trac] #51794: An author_name query with nonexistent user returns posts with no author

WordPress Trac noreply at wordpress.org
Tue Nov 17 03:53:57 UTC 2020


#51794: An author_name query with nonexistent user returns posts with no author
--------------------------+-----------------------------
 Reporter:  trepmal       |      Owner:  (none)
     Type:  defect (bug)  |     Status:  new
 Priority:  normal        |  Milestone:  Awaiting Review
Component:  Query         |    Version:
 Severity:  normal        |   Keywords:  has-patch
  Focuses:                |
--------------------------+-----------------------------
 This was initially noticed on a production site where an author URL with a
 bogus author slug (e.g.
 http://local.wordpress.test/author/thisuserdoesnotexist/) was returning
 posts.

 If an `author_name` query is made with gibberish (or any nonexistent
 author slug), the query will return results for `post_author = 0`.

 {{{
 wp> $q = new WP_Query( [ 'author_name' => 'thisuserdoesnotexist' ] );
 [...]
 wp> $q->is_404;
 bool(false)
 wp> $q->found_posts;
 int(3562)
 wp> $q->request;
 string(213) "SELECT SQL_CALC_FOUND_ROWS  wp_posts.ID FROM wp_posts  WHERE
 1=1  AND (wp_posts.post_author = 0) AND wp_posts.post_type = 'post' AND
 (wp_posts.post_status = 'publish')  ORDER BY wp_posts.post_date DESC LIMIT
 0, 10"
 }}}

 Are there a lot of sites out there with posts assigned to a 0 author? No
 idea, but my test site has a lot from generating posts via WP_CLI.

 The issue stems from wp-includes/class-wp-query.php#L2254-L2258...

 {{{
 $q['author']      = get_user_by( 'slug', $q['author_name'] );
 if ( $q['author'] ) {
         $q['author'] = $q['author']->ID;
 }
 $whichauthor .= " AND ({$wpdb->posts}.post_author = " . absint(
 $q['author'] ) . ')';
 }}}

 ...where a potentially false result from `get_user_by()` is cast to an int
 and used in a query.


 With the included patch, this is the result of the same query:

 {{{
 wp> $q->is_404
 bool(true)
 wp> $q->found_posts
 int(0)
 wp> $q->request
 string(250) "SELECT SQL_CALC_FOUND_ROWS  wp_posts.ID FROM wp_posts  WHERE
 1=1  AND wp_posts.post_author NOT IN (0)  AND (wp_posts.post_author = 0)
 AND wp_posts.post_type = 'post' AND (wp_posts.post_status = 'publish')
 ORDER BY wp_posts.post_date DESC LIMIT 0, 10"
 }}}

 The patch is a hack though, relying on another `absint()` to make our
 query search for posts that both are and are not by `0` :) There's
 probably a better way.

 But, removing the hacky `$qv['author'] = $qv['author_name'];` line leaves
 this, which although returns a 404 to the browser, still runs the query:

 {{{
 wp> $q->is_404
 bool(true)
 wp> $q->found_posts
 int(3562)
 wp> $q->request
 string(213) "SELECT SQL_CALC_FOUND_ROWS  wp_posts.ID FROM wp_posts  WHERE
 1=1  AND (wp_posts.post_author = 0) AND wp_posts.post_type = 'post' AND
 (wp_posts.post_status = 'publish')  ORDER BY wp_posts.post_date DESC LIMIT
 0, 10"
 }}}

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


More information about the wp-trac mailing list