diff --git a/src/wp-admin/includes/class-wp-list-table.php b/src/wp-admin/includes/class-wp-list-table.php index 0795da27535c6..58a4dd47adec4 100644 --- a/src/wp-admin/includes/class-wp-list-table.php +++ b/src/wp-admin/includes/class-wp-list-table.php @@ -1040,9 +1040,7 @@ protected function pagination( $which ) { $current = $this->get_pagenum(); $removable_query_args = wp_removable_query_args(); - $current_url = set_url_scheme( 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] ); - - $current_url = remove_query_arg( $removable_query_args, $current_url ); + $current_url = remove_query_arg( $removable_query_args ); $page_links = array(); @@ -1394,8 +1392,7 @@ public function get_column_count() { public function print_column_headers( $with_id = true ) { list( $columns, $hidden, $sortable, $primary ) = $this->get_column_info(); - $current_url = set_url_scheme( 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] ); - $current_url = remove_query_arg( 'paged', $current_url ); + $current_url = remove_query_arg( 'paged' ); // When users click on a column header to sort by other columns. if ( isset( $_GET['orderby'] ) ) { diff --git a/src/wp-admin/includes/misc.php b/src/wp-admin/includes/misc.php index 3724684ffd428..8ae70daef9b66 100644 --- a/src/wp-admin/includes/misc.php +++ b/src/wp-admin/includes/misc.php @@ -1406,7 +1406,11 @@ function wp_admin_canonical_url() { } // Ensure we're using an absolute URL. - $current_url = set_url_scheme( 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] ); + // Build the canonical URL using the configured admin URL to avoid issues + // with reverse proxies that expose a different host via HTTP_HOST. + $path = parse_url( $_SERVER['REQUEST_URI'], PHP_URL_PATH ); + $query = parse_url( $_SERVER['REQUEST_URI'], PHP_URL_QUERY ); + $current_url = admin_url( ltrim( $path, '/' ) . ( $query ? '?' . $query : '' ) ); $filtered_url = remove_query_arg( $removable_query_args, $current_url ); /** diff --git a/tests/phpunit/tests/admin/wpListTable.php b/tests/phpunit/tests/admin/wpListTable.php index b3de66659b308..a6d9aaeedda1d 100644 --- a/tests/phpunit/tests/admin/wpListTable.php +++ b/tests/phpunit/tests/admin/wpListTable.php @@ -592,4 +592,60 @@ public function test_search_box_works_with_orderby_string() { $this->assertStringContainsString( $expected_html, $actual ); } + + /** + * @ticket 16858 + */ + public function test_pagination_should_not_use_http_host_for_urls() { + $fake_host = 'internal.proxy.example.local'; + $original_host = $_SERVER['HTTP_HOST'] ?? ''; + + $_SERVER['HTTP_HOST'] = $fake_host; + $_SERVER['REQUEST_URI'] = '/wp-admin/edit.php?post_type=post'; + + $pagination_args = new ReflectionProperty( $this->list_table, '_pagination_args' ); + if ( PHP_VERSION_ID < 80100 ) { + $pagination_args->setAccessible( true ); + } + $pagination_args->setValue( + $this->list_table, + array( + 'total_items' => 100, + 'total_pages' => 5, + 'per_page' => 20, + ) + ); + + $actual = get_echo( array( $this->list_table, 'pagination' ), array( 'top' ) ); + + $_SERVER['HTTP_HOST'] = $original_host; + + $this->assertStringNotContainsString( + $fake_host, + $actual, + 'Pagination links should not contain the raw HTTP_HOST value.' + ); + } + + + /** + * @ticket 16858 + */ + public function test_print_column_headers_should_not_use_http_host_for_urls() { + $fake_host = 'internal.proxy.example.local'; + $original_host = $_SERVER['HTTP_HOST'] ?? ''; + + $_SERVER['HTTP_HOST'] = $fake_host; + $_SERVER['REQUEST_URI'] = '/wp-admin/edit.php?post_type=post'; + + $actual = get_echo( array( $this->list_table, 'print_column_headers' ) ); + + $_SERVER['HTTP_HOST'] = $original_host; + + $this->assertStringNotContainsString( + $fake_host, + $actual, + 'Column header links should not contain the raw HTTP_HOST value.' + ); + } }