Make WordPress Core


Ignore:
Timestamp:
02/16/2024 11:32:48 PM (3 years ago)
Author:
peterwilsoncc
Message:

Canonical: Limit post types searched by redirect_guess_404_permalink().

Limit the post types searched in redirect_guess_404_permalink() to public, searchable post types. This prevents redirects to 404 pages and the exposure of private post type slugs.

Props francescocarlucci, peterwilsoncc, rajinsharwar.
Fixes #59795.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/canonical.php

    r57357 r57645  
    950950
    951951        if ( get_query_var( 'name' ) ) {
     952                $publicly_viewable_statuses   = array_filter( get_post_stati(), 'is_post_status_viewable' );
     953                $publicly_viewable_post_types = array_filter( get_post_types( array( 'exclude_from_search' => false ) ), 'is_post_type_viewable' );
     954
    952955                /**
    953956                 * Filters whether to perform a strict guess for a 404 redirect.
     
    970973                if ( get_query_var( 'post_type' ) ) {
    971974                        if ( is_array( get_query_var( 'post_type' ) ) ) {
     975                                $post_types = array_intersect( get_query_var( 'post_type' ), $publicly_viewable_post_types );
     976                                if ( empty( $post_types ) ) {
     977                                        return false;
     978                                }
    972979                                $where .= " AND post_type IN ('" . join( "', '", esc_sql( get_query_var( 'post_type' ) ) ) . "')";
    973980                        } else {
     981                                if ( ! in_array( get_query_var( 'post_type' ), $publicly_viewable_post_types, true ) ) {
     982                                        return false;
     983                                }
    974984                                $where .= $wpdb->prepare( ' AND post_type = %s', get_query_var( 'post_type' ) );
    975985                        }
    976986                } else {
    977                         $where .= " AND post_type IN ('" . implode( "', '", get_post_types( array( 'public' => true ) ) ) . "')";
     987                        $where .= " AND post_type IN ('" . implode( "', '", esc_sql( $publicly_viewable_post_types ) ) . "')";
    978988                }
    979989
     
    988998                }
    989999
    990                 $publicly_viewable_statuses = array_filter( get_post_stati(), 'is_post_status_viewable' );
    9911000                // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
    9921001                $post_id = $wpdb->get_var( "SELECT ID FROM $wpdb->posts WHERE $where AND post_status IN ('" . implode( "', '", esc_sql( $publicly_viewable_statuses ) ) . "')" );
Note: See TracChangeset for help on using the changeset viewer.