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.