2019-03-15 @ 10:52: Referrer hell Browsers | PHP | Security

Relying on the HTTP referrer is bad. Everyone knows this, but at least the WordPress developers seem to ignore the fact. Also I never understood, why PHP keeps writing HTTP_REFERER with a single “R” in the middle. The correct term would be HTTP_REFERRER.

Anyway, instead of storing the current URL in $_SESSION[‘HTTP_REFERRER’] as one would normally do, WordPress checks for $_SERVER[‘HTTP_REFERER’] instead.

The PHP documentation is very clear on this to not trust this referrer:

‘HTTP_REFERER’
The address of the page (if any) which referred the user agent to the current page. This is set by the user agent. Not all user agents will set this, and some provide the ability to modify HTTP_REFERER as a feature. In short, it cannot really be trusted.

Imagine the following case: you run WordPress from a sub-folder of the root-directory and the referrer is – for whatever reason – set to the web-root of the server, rather than the web-root of your WordPress installation. In fact this is the case on my development machine; I talk about the reason somewhere below.

Now, when you try to delete/recycle a post/page/whatever WordPress checks the referrer in post.php in line 55:

$sendback = wp_get_referer();
if ( ! $sendback ||
	 strpos( $sendback, 'post.php' ) !== false ||
	 strpos( $sendback, 'post-new.php' ) !== false ) {
	if ( 'attachment' == $post_type ) {
		$sendback = admin_url( 'upload.php' );
	} else {
		$sendback = admin_url( 'edit.php' );
		if ( ! empty( $post_type ) ) {
			$sendback = add_query_arg( 'post_type', $post_type, $sendback );
		}
	}
} else {
	$sendback = remove_query_arg( array( 'trashed', 'untrashed', 'deleted', 'ids' ), $sendback );
}

For instance, the code above is taken from WordPress 5.1.1.

So, what happens when the referrer returned by wp_get_referer() contains the wrong URL? You’ll get redirected to anywhere, but the correct location. The only way to somehow fix this without messing with the code is to disable the referrer entirely. You still won’t get to the correct location, but at least you remain inside the WordPress web-root.

Why is the referrer wrong?

As stated above the referrer is set by the user agent (e.g. the browser). It seems like my Waterfox does not set the referrer correctly. For instance, it does not occur in Firefox and Opera. Looking at about:config in Waterfox I found the setting “network.http.referer.trimmingPolicy” being set to “2”. According to this page it will strip the referrer to its origin without any query strings etc.

Setting it back to its default solved the issue, but enables the browser to send the full referrer, which is not desirable by privacy means. On the other hand it did not break any other pages besides the WordPress backend, so I guess it’s time for the WordPress developers to fix their code.



  • About

    Destabilizing cishetero amatonormativity. Providing disruption as a service. Once you know the way, you see it in all things. Unless you puke, faint or die, keep going. Also we never asked for this. I̸͝t̸̑ ̵̽i̷͗s̶͐ ̵͝a̶͒l̷ ͍r̷ ̗͕e̵͑a̶͌d̸̄y̷̚ ̶̀ ͓͑t̷̚ô̶o̸ ̥ ̶́ ̡l̷͝a̶̽t̵͒ė̶.̸ ̋͑

  • Got something interesting?

    You think you got something which should be on this site? Then contact us. You want something removed from this site, because you think it should not be here? Then go fuck yourself. This is a free website. Free as in freedom. It tolerates every opinion from everyone. However, it does not tolerate things which are illegal according to the Swiss legislation.

  • Disclaimer

    We cannot be held responsible for any kind of direct, indirect or consequential damages caused by the stuff and or opinions we provide here. Use this on your own risk. Don’t blame us if something goes wrong or totally messes up your machine, your life or whatever. If this is unacceptable for you then go away and never come back again. Thank you!