Make WordPress Core

Opened 11 years ago

Last modified 4 months ago

#36201 reopened defect (bug)

Admin Pagination URLs Use Wrong Hostname

Reported by: grimmdude Owned by:
Priority: normal Milestone: Future Release
Component: Administration Version:
Severity: normal Keywords: has-patch needs-testing dev-feedback
Cc: Focuses: administration

Description

The pagination links on the posts/pages screen uses the wrong host in some cases. Particularly for my case I have a Wordpress blog installed on a separate server from my main website, but it's hosted as a subdirectory /blog on the main site using the mod_proxy Apache module. So the pagination links are coming through using the wrong host like this:

​http://1647760595.us-east-1.elb.amazonaws.com/wp-admin/edit.php?paged=2

It seems like these pagination links are the only ones with this issue, and I believe it's because of how they are being constructed.

I've attached a patch that solves the issue for me.

-Garrett

Attachments (3)

class-wp-list-table.diff​ (584 bytes ) - added by grimmdude 11 years ago.
wp-admin-url-36201.patch​ (2.0 KB ) - added by kwhat 7 years ago.
Updated patch, please apply!
class-wp-list-table-36201.patch​ (616 bytes ) - added by waddles 7 years ago.
updated for wordpress > 4.6

Download all attachments as: .zip

Change History (50)

#1 @swissspidy
11 years ago

  • Focuses administration removed
  • Keywords has-patch added
  • Milestone Awaiting Review → Future Release

#2 @johnbillion
11 years ago

  • Keywords needs-testing added
  • Version trunk

Related: #35561.

I'm not sure why there are a few links constructed like this in core. I can't immediately think of anything that would break if they were corrected so they used admin_url().

Does #35561 affect your site too, @grimmdude?

#3 @grimmdude
11 years ago

@johnbilliion, yes it does look like #35561 is an issue for me as well. Sounds like that OP and I have a similar setup. Thanks,

-Garrett

#4 @johnbillion
10 years ago

#38414 was marked as a duplicate.

#5 @grimmdude
10 years ago

Any update on this ticket? Thanks,

-Garrett

#6 @grimmdude
10 years ago

May I ask what the hold up is on this? Seems like a straightforward fix,

-Garrett

#8 @grimmdude
10 years ago

Hi @SergeyBiryukov,

Just checking in on this one. Does your comment mean that this is something that's being fixed soon? Thanks,

-Garrett

#9 @swissspidy
9 years ago

  • Milestone Future Release → 4.8

The earlier we can test this, the better.

#10 @DaveFX
9 years ago

  • Keywords dev-feedback added

Works for me

#11 @swissspidy
9 years ago

@DaveFX That's not how the dev-feedback keyword should be used. See ​https://make.wordpress.org/core/handbook/contribute/trac/keywords/

This ticket was mentioned in ​Slack in #core by obenland. ​View the logs.


9 years ago

#13 @obenland
9 years ago

  • Milestone 4.8 → Future Release

#14 @ketanumretiya030
9 years ago

  • Keywords close added
  • Resolution → maybelater
  • Status new → closed

i have test pagination in admin with pag, post, and media file all is working fine.

#15 @grimmdude
9 years ago

  • Resolution maybelater
  • Status closed → reopened

Hi @ketanumretiya030,

I still see this as an issue when using a proxy as mentioned in the original post. From what I can tell, as long as this URL is built with a concatenation of $_SERVER vars as opposed to using admin_url() then this problem will persist.

​https://github.com/WordPress/WordPress/blob/aaf99e691391cfceb004d848450dbbf3344b1bee/wp-admin/includes/class-wp-list-table.php#L793

-Garrett

#16 @viliusl
8 years ago

As stated above, this is rare problem, but still happens if WP is used with proxy.

And fix is easy: take host from DB, not form $_SERVER (WP already doing it, sadly, not everywhere).

​https://github.com/WordPress/WordPress/blob/aaf99e691391cfceb004d848450dbbf3344b1bee/wp-admin/includes/class-wp-list-table.php#L793

<?php
$siteurl = get_option('siteurl');
$current_url = parse_url($siteurl, PHP_URL_SCHEME) . '://' . parse_url($siteurl, PHP_URL_HOST) . $_SERVER['REQUEST_URI'];

p.s. similar situation with sorting:
​https://github.com/WordPress/WordPress/blob/aaf99e691391cfceb004d848450dbbf3344b1bee/wp-admin/includes/class-wp-list-table.php#L1077

#17 follow-up: @wellmadedigital
7 years ago

We had this same issue and stumbled on this:

"The site’s wp-config.php file needs to be updated with a $_SERVERHTTP_HOST definition pointing at the main site URL (example.com in the example we’ve been considering)." Source: ​https://kinsta.com/knowledgebase/reverse-proxy/

Adding $_SERVER['HTTP_HOST'] = 'yoursite.com'; to our ProxyPass settings in wp-config resolved it.

As an example:

Site exists at subdomain.yoursite.com. Proxied to www.yoursite.com/subdomain

Added to wp-config to make this work and resolve the Wordpress Admin URL issues (pagination, editing users, etc.):

<?php
# ProxyPass Settings 
# 
# DO NOT REMOVE: overriding the following variables is
# required to ensure that any request /journal/* is handled
$_SERVER['REQUEST_URI'] = '/subdomain' . $_SERVER['REQUEST_URI'];
$_SERVER['SCRIPT_NAME'] = '/subdomain' . $_SERVER['SCRIPT_NAME'];
$_SERVER['PHP_SELF'] = '/subdomain' . $_SERVER['PHP_SELF'];
$_SERVER['HTTP_HOST'] = 'www.yoursite.com';

I still agree with the OP that this feels like a core bug, but I wanted to throw this out there as an alternative solution that doesn't require core revision.

Version 0, edited 7 years ago by wellmadedigital (next)

#18 @ocean90
7 years ago

#46037 was marked as a duplicate.

#19 @ocean90
7 years ago

#47033 was marked as a duplicate.

This ticket was mentioned in ​Slack in #slackhelp by ooglek. ​View the logs.


7 years ago

#21 @ooglek
7 years ago

Let's make this happen! Is the best path here using admin_url(), get_option('siteurl'), get_site_url() or some other replacement for the hardcoded $_SERVER['HTTP_HOST'] ?

admin_url() calls get_admin_url() which calls get_site_url() which calls get_option('siteurl')

It seems admin_url() is a higher level method and better place to start. The original diff seems appropriate.

There are only three places left in the wp-admin/ directory where HTTP_HOST is referenced:

in misc.php 5.1.1

<?php
1164
1165     // Ensure we're using an absolute URL.
1166     $current_url  = set_url_scheme( 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] );
1167     $filtered_url = remove_query_arg( $removable_query_args, $current_url );

In class-wp-list-table.php 5.1.1

<?php
 796         $removable_query_args = wp_removable_query_args();
 797
 798         $current_url = set_url_scheme( 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] );
 799
 800         $current_url = remove_query_arg( $removable_query_args, $current_url );

and

<?php
1080         list( $columns, $hidden, $sortable, $primary ) = $this->get_column_info();
1081
1082         $current_url = set_url_scheme( 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] );
1083         $current_url = remove_query_arg( 'paged', $current_url );
1084

Let's fix this.

#22 @SergeyBiryukov
7 years ago

#47356 was marked as a duplicate.

#23 @kwhat
7 years ago

What can be done to speed up the adoption of the above fixes? Can I make a pull-request or do we need a diff file or is something else holding this up?

@kwhat
7 years ago

Updated patch, please apply!

@waddles
7 years ago

updated for wordpress > 4.6

#24 @waddles
7 years ago

One would think forcing a url scheme to http:// would be a security concern in 2019.

I think the original solution is best so I updated the patch to support changes made in 4.6.

#25 @grimmdude
7 years ago

  • Focuses administration added

Wow, this is still pending? I created this ticket over three years ago :o

#26 @kwhat
7 years ago

I have a feeling this ticket has fallen into the backlog abyss. I am not holding my breath that this will be addressed in the next 3 years. You know when you stumble across that 17 year old bug on redit that is finally getting fixed? Yah, its kind of like that.

#27 @viliusl
7 years ago

  • Keywords close removed

#28 @tinodjwp
7 years ago

Latest update caused problems. Can you please fix this?

#29 @liemdo
6 years ago

It's been a few years already and it seems the problem still persists. Any updates on this one?

#30 @ocean90
6 years ago

#50157 was marked as a duplicate.

#31 follow-up: @jschodermedikura
6 years ago

We have the exact same issue and only really dirty workarounds. It takes longer to argue about this than to actually fix this. To quote John Oliver: How is this still a thing?

#32 in reply to: ↑ 31 @viliusl
6 years ago

Replying to jschodermedikura:

...It takes longer to argue about this than to actually fix this...

Its funny and sad at the same time.
I predict this discussion will continue for at least 3 years more. Now somebody prove me wrong ...

#33 @ocean90
6 years ago

#50365 was marked as a duplicate.

#34 @higuita
6 years ago

So 4 years later, having already a patch for at least 1 year and still not fixed :(

How about a plugin to fix this? is it possible?

Lets try to ping the core commiters already in the ticket!

@ocean90 @SergeyBiryukov @swissspidy @obenland

Last edited 6 years ago by higuita (previous) (diff)

#35 @viliusl
6 years ago

How about a plugin to fix this? is it possible?

Not possible to fix with plugin in clean way, unless using methods, that gives even more problems (ob_start).

Last edited 6 years ago by viliusl (previous) (diff)

This ticket was mentioned in ​Slack in #core-media by johnbillion. ​View the logs.


6 years ago

#37 in reply to: ↑ 17 @joelfbr
6 years ago

Thank you for the great advice! this finally helped me in a similar issue.

Now, I am wondering which file we have to edit to force WP to always respond with the correct host.
see my question on ​https://stackoverflow.com/questions/65671943/wordpress-redirect-to-main-host

Replying to wellmadedigital:

We had this same issue and stumbled on this:

"The site’s wp-config.php file needs to be updated with a $_SERVERHTTP_HOST definition pointing at the main site URL (example.com in the example we’ve been considering)." Source: ​https://kinsta.com/knowledgebase/reverse-proxy/

Adding $_SERVER['HTTP_HOST'] = 'yoursite.com'; to our ProxyPass settings in wp-config resolved it.

As an example:

Site exists at subdomain.yoursite.com. Proxied to www.yoursite.com/subdomain

Added to wp-config to make this work and resolve many of the WordPress Admin URL issues (pagination, editing users, etc.):

<?php
# ProxyPass Settings 
# 
# DO NOT REMOVE: overriding the following variables is
# required to ensure that any request /journal/* is handled
$_SERVER['REQUEST_URI'] = '/subdomain' . $_SERVER['REQUEST_URI'];
$_SERVER['SCRIPT_NAME'] = '/subdomain' . $_SERVER['SCRIPT_NAME'];
$_SERVER['PHP_SELF'] = '/subdomain' . $_SERVER['PHP_SELF'];
$_SERVER['HTTP_HOST'] = 'www.yoursite.com';

I still agree with the OP that this feels like a core bug, but I wanted to throw this out there as an alternative solution that doesn't require core revision.

This ticket was mentioned in ​PR #1503 on ​WordPress/wordpress-develop by ​jefferyto.


5 years ago
#38

Currently, WP_List_Table uses $_SERVER['HTTP_HOST'] to build pagination and column header links. These links will point to an incorrect host if $_SERVER['HTTP_HOST'] does not match the site URL host, e.g. when Wordpress is used behind a reverse proxy.

This uses admin_url() so that these links will take the configured site URL into account.

Trac ticket: https://core.trac.wordpress.org/ticket/36201

#39 @jefferyto
5 years ago

As mentioned by the GitHub bot, I have a PR (​https://github.com/WordPress/wordpress-develop/pull/1503) that addresses this issue - would appreciate it if a core committer can take a look.

On setting $_SERVER['HTTP_HOST'] in wp-config.php: For multisite installations using subdomains, this isn't a viable workaround because WordPress uses $_SERVER['HTTP_HOST'] to figure out which site to show/edit/etc. If $_SERVER['HTTP_HOST'] is set to a value that isn't one of the subdomains WordPress knows about, e.g. the public name of a reverse proxy server, WordPress will prompt you to add a new site to the network.

#40 follow-ups: @timinaust
5 years ago

I found setting HTTP_HOST caused other redirect issues. My workaround to this - providing you have access to the proxy...

Set the proxy to add a header on requests being passed through with the request host name, then add the following at the end of wp-config.php. It corrects pagination/sorting for both normal and ajax admin calls.

Example is for apache proxy, nginx proxy should work exactly the same if you add the same header.

/**
 * Filter to fix up admin URLs when running behind a reverse proxy.
 * On the proxy, add a header to requests for X_ORIGINAL_HOST.
 *
 * On and apache proxy add the following RequestHeader line in the proxy block.
 *   <Location ...>
 *     ProxyPass ....
 *     ProxyPassReverse ....
 *      ....
 *     RequestHeader set X-Original-Host "expr=%{HTTP_HOST}"
 *    ....
 *   </Location>
 */
function proxied_url_rewrite ($url,$scheme,$orig_scheme) {
        if ($_SERVER["HTTP_X_ORIGINAL_HOST"] && ($scheme == "https" || $scheme == "http") && $_SERVER['HTTP_HOST'] != $_SERVER["HTTP_X_ORIGINAL_HOST"] )
                $url = str_replace("://".$_SERVER['HTTP_HOST']."/", "://".$_SERVER["HTTP_X_ORIGINAL_HOST"]."/",$url);
        return $url;
};
if ( is_admin() && $_SERVER["HTTP_X_IS_REVERSE_PROXY"]) add_filter('set_url_scheme','proxied_url_rewrite',10,3);

You may also need to add in wp-config.php if you are proxying from https -> http

$_SERVER['HTTPS'] = 'on';


#41 in reply to: ↑ 40 ; follow-up: @jefferyto
5 years ago

Replying to timinaust:

I found setting HTTP_HOST caused other redirect issues. My workaround to this - providing you have access to the proxy...

Set the proxy to add a header on requests being passed through with the request host name, then add the following at the end of wp-config.php. It corrects pagination/sorting for both normal and ajax admin calls.

Did you try my fix (at ​https://github.com/WordPress/wordpress-develop/pull/1503)? It does not require setting HTTP_HOST.

#42 in reply to: ↑ 41 ; follow-up: @timinaust
5 years ago

Replying to jefferyto:

Did you try my fix (at ​https://github.com/WordPress/wordpress-develop/pull/1503)? It does not require setting HTTP_HOST.

Hi, it looks like it would address the issue, but I am reluctant to patch to core files which I would forget about when a new versions comes along.

Hopefully this will be resolved properly some time soon, however judging by the age of the ticket, we may be waiting a while yet.

#43 in reply to: ↑ 42 @jefferyto
5 years ago

Replying to timinaust:

Replying to jefferyto:

Did you try my fix (at ​https://github.com/WordPress/wordpress-develop/pull/1503)? It does not require setting HTTP_HOST.

Hi, it looks like it would address the issue, but I am reluctant to patch to core files which I would forget about when a new versions comes along.

Agree about patching core files - I just hope to have more people test the patch to verify that it works correctly.

#44 @alexishuxley
5 years ago

Any news when this will be fixed? A WordPress server behind a frontend webserver is not an uncommon configuration and for something as basic as the next/previous page links on the posts/pages listing pages to be broken for six years is frankly ridiculous, especially when several generous people have submitted patches to fix it.

This bug causes problems for plugins (e.g. TablePress) that use the same helper functions (e.g. see ​this bug report wrongly filed against TablePress).

​ajbeaven commented on ​PR #1503:


3 years ago
#45

Is there any timeline for when approved changes like this are merged in or is this PR still being considered?

#46 in reply to: ↑ 40 @provesource
2 years ago

I was wondering what kind of redirect issues did you have?
We have wordpress behind a reverse proxy + on a directory of the main domain
Setting the $_SERVERHTTP_HOST and other params seems to have fixed the issue for us.

Had to go through the wordpress core code to find this issue before stumbling on this now 8 year old (!!) ticket.

Replying to timinaust:

I found setting HTTP_HOST caused other redirect issues. My workaround to this - providing you have access to the proxy...

Set the proxy to add a header on requests being passed through with the request host name, then add the following at the end of wp-config.php. It corrects pagination/sorting for both normal and ajax admin calls.

Example is for apache proxy, nginx proxy should work exactly the same if you add the same header.

/**
 * Filter to fix up admin URLs when running behind a reverse proxy.
 * On the proxy, add a header to requests for X_ORIGINAL_HOST.
 *
 * On and apache proxy add the following RequestHeader line in the proxy block.
 *   <Location ...>
 *     ProxyPass ....
 *     ProxyPassReverse ....
 *      ....
 *     RequestHeader set X-Original-Host "expr=%{HTTP_HOST}"
 *    ....
 *   </Location>
 */
function proxied_url_rewrite ($url,$scheme,$orig_scheme) {
        if ($_SERVER["HTTP_X_ORIGINAL_HOST"] && ($scheme == "https" || $scheme == "http") && $_SERVER['HTTP_HOST'] != $_SERVER["HTTP_X_ORIGINAL_HOST"] )
                $url = str_replace("://".$_SERVER['HTTP_HOST']."/", "://".$_SERVER["HTTP_X_ORIGINAL_HOST"]."/",$url);
        return $url;
};
if ( is_admin() && $_SERVER["HTTP_X_IS_REVERSE_PROXY"]) add_filter('set_url_scheme','proxied_url_rewrite',10,3);

You may also need to add in wp-config.php if you are proxying from https -> http

$_SERVER['HTTPS'] = 'on';


#47 @logicrays
4 months ago

Hello @grimmdude

According to my thoughts, the current implementation relies on

$_SERVER['HTTP_HOST']

to build admin pagination URLs.
This can generate incorrect links when WordPress is deployed behind reverse proxies, load balancers, or subdirectory mappings.
Since WordPress already provides canonical admin URLs through admin_url(), we should avoid constructing URLs manually from server variables.

Suggested approach:

  • Use admin_url() as the base URL.
  • Append the current request path using REQUEST_URI.
  • Apply wp_unslash() before using superglobals.
  • Continue removing query arguments via remove_query_arg() as needed.

This change improves compatibility with proxied environments and aligns with WordPress URL generation best practices.

Note: See TracTickets for help on using tickets.