Commit 82db6295b7 for wordpress.org
commit 82db6295b7eabfa92224f254c5e9a82afd6b5a71
Author: jorbin <jorbin@git.wordpress.org>
Date: Thu Nov 12 21:35:54 2026 +0000
Rewrite Rules: Always redirect random content requests.
When the randomly selected post's permalink was empty or on a host outside `allowed_redirect_hosts`, the request was not redirected and instead rendered the post as a one-post archive with a `200` status. That response was sent without the no-cache and noindex headers, so a page cache could store one post for `/random/`, and the post's content was displayed even though its permalink pointed elsewhere.
The request now ends as soon as a post is selected, sending the headers and redirecting with `wp_redirect()` rather than `wp_safe_redirect()`. A permalink can only point to another site if a plugin filters it to do so, so it is treated as an intentional redirect location.
Developed in: https://github.com/WordPress/wordpress-develop/pull/15825
Follow-up to r64402.
Props renehermi, jorbin, peterwilsoncc, ssebuwufumoses.
Fixes #66625. See #64498.
Built from https://develop.svn.wordpress.org/trunk@65440
git-svn-id: http://core.svn.wordpress.org/trunk@64579 1a063a9b-81f0-0310-95a4-ce76da25c4cd
diff --git a/wp-includes/class-wp.php b/wp-includes/class-wp.php
index 1907844e95..d7c2add374 100644
--- a/wp-includes/class-wp.php
+++ b/wp-includes/class-wp.php
@@ -720,9 +720,9 @@ class WP {
* - {@see wp_random_content_post_limits()} on the {@see 'post_limits'} filter.
*
* If no post is selected, for example on an empty archive, the request is a 404 as
- * there is no post to redirect to. If a post is selected but the request is not
- * redirected, the request continues with the results of the main query. The main
- * query is not run again.
+ * there is no post to redirect to. If a post is selected, the request ends with
+ * the redirect. Otherwise the request continues with the results of the main
+ * query, which is not run again.
*
* @since 7.2.0
*
diff --git a/wp-includes/query.php b/wp-includes/query.php
index 40a9a285c9..7a21ba50df 100644
--- a/wp-includes/query.php
+++ b/wp-includes/query.php
@@ -1465,13 +1465,16 @@ function wp_random_content_post_limits( $limits, WP_Query $query ): string {
* Redirects random content requests to the randomly selected post.
*
* Called by {@see WP::handle_random()} immediately after the main query selects the
- * random post, to avoid unnecessary processing before the redirect. As the redirect
- * is sent before {@see WP::send_headers()}, the headers preventing the redirect being
- * cached or indexed are sent with it.
+ * random post, to avoid unnecessary processing before the redirect. The headers
+ * preventing the response being cached or indexed are sent as soon as a post is
+ * selected, before {@see WP::send_headers()}, so they are sent with the redirect.
+ *
+ * The request ends once a post is selected. The redirect is to the post's permalink
+ * as returned by {@see get_permalink()}, including a permalink filtered to be on
+ * another site.
*
* If no post is selected, for example on an empty archive, {@see WP::handle_random()}
- * handles the request as a 404. If the post's permalink is on another site, the
- * request is handled as a regular archive request.
+ * handles the request as a 404.
*
* @since 7.2.0
*
@@ -1484,22 +1487,16 @@ function wp_random_content_redirect(): void {
return;
}
- $location = get_permalink( $wp_query->post );
-
- // Only consider redirecting permitted locations so wp_safe_redirect doesn't redirect to the fallback.
- if ( ! $location || ! wp_validate_redirect( $location, '' ) ) {
- return;
- }
-
nocache_headers();
if ( ! headers_sent() ) {
header( 'X-Robots-Tag: noindex, follow' );
}
- if ( wp_safe_redirect( $location, 302 ) ) {
- exit;
- }
+ $location = get_permalink( $wp_query->post );
+
+ wp_redirect( $location, 302 );
+ exit;
}
/**
diff --git a/wp-includes/version.php b/wp-includes/version.php
index 5544243a5d..12377a2fd4 100644
--- a/wp-includes/version.php
+++ b/wp-includes/version.php
@@ -16,7 +16,7 @@
*
* @global string $wp_version
*/
-$wp_version = '7.2-beta5-65439';
+$wp_version = '7.2-beta5-65440';
/**
* Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.