From 3a358c33d30f8904d3492e834a01370f5b971ca5 Mon Sep 17 00:00:00 2001 From: Pascal Birchler Date: Tue, 12 Jan 2016 08:31:10 +0000 Subject: [PATCH] Introduce `wp_get_raw_referer()` to retrieve unvalidated referer. For things like redirects `wp_get_referer()` should be used instead. Props voldemortensen for initial patch. Fixes #27152. git-svn-id: https://develop.svn.wordpress.org/trunk@36266 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-includes/functions.php | 29 ++++++++++++--- tests/phpunit/tests/functions/referer.php | 45 +++++++++++++++++++---- 2 files changed, 61 insertions(+), 13 deletions(-) diff --git a/src/wp-includes/functions.php b/src/wp-includes/functions.php index 6dbc510af5..b3fddfd2b8 100644 --- a/src/wp-includes/functions.php +++ b/src/wp-includes/functions.php @@ -1517,13 +1517,11 @@ function wp_original_referer_field( $echo = true, $jump_back_to = 'current' ) { * @return false|string False on failure. Referer URL on success. */ function wp_get_referer() { - if ( ! function_exists( 'wp_validate_redirect' ) ) + if ( ! function_exists( 'wp_validate_redirect' ) ) { return false; - $ref = false; - if ( ! empty( $_REQUEST['_wp_http_referer'] ) ) - $ref = wp_unslash( $_REQUEST['_wp_http_referer'] ); - elseif ( ! empty( $_SERVER['HTTP_REFERER'] ) ) - $ref = wp_unslash( $_SERVER['HTTP_REFERER'] ); + } + + $ref = wp_get_raw_referer(); if ( $ref && $ref !== wp_unslash( $_SERVER['REQUEST_URI'] ) && $ref !== home_url() . wp_unslash( $_SERVER['REQUEST_URI'] ) ) { return wp_validate_redirect( $ref, false ); @@ -1532,6 +1530,25 @@ function wp_get_referer() { return false; } +/** + * Retrieve unvalidated referer from '_wp_http_referer' or HTTP referer. + * + * Do not use for redirects, use wp_get_referer() instead. + * + * @since 4.5.0 + * + * @return string|bool Referer URL on success, false on failure. + */ +function wp_get_raw_referer() { + if ( ! empty( $_REQUEST['_wp_http_referer'] ) ) { + return wp_unslash( $_REQUEST['_wp_http_referer'] ); + } else if ( ! empty( $_SERVER['HTTP_REFERER'] ) ) { + return wp_unslash( $_SERVER['HTTP_REFERER'] ); + } + + return false; +} + /** * Retrieve original referer that was posted, if it exists. * diff --git a/tests/phpunit/tests/functions/referer.php b/tests/phpunit/tests/functions/referer.php index 053e5784cf..07e0f66a0a 100644 --- a/tests/phpunit/tests/functions/referer.php +++ b/tests/phpunit/tests/functions/referer.php @@ -6,21 +6,20 @@ * @group functions.php */ class Tests_Functions_Referer extends WP_UnitTestCase { - private $request = array(); - private $server = array(); - public function setUp() { parent::setUp(); - $this->server = $_SERVER; - $this->request = $_REQUEST; + $_SERVER['HTTP_REFERER'] = ''; + $_SERVER['REQUEST_URI'] = ''; + $_REQUEST['_wp_http_referer'] = ''; } public function tearDown() { parent::tearDown(); - $_SERVER = $this->server; - $_REQUEST = $this->request; + $_SERVER['HTTP_REFERER'] = ''; + $_SERVER['REQUEST_URI'] = ''; + $_REQUEST['_wp_http_referer'] = ''; } public function _fake_subfolder_install() { @@ -122,4 +121,36 @@ class Tests_Functions_Referer extends WP_UnitTestCase { $this->assertSame( 'http://another.example.org/test.php?id=123', wp_get_referer() ); remove_filter( 'allowed_redirect_hosts', array( $this, 'filter_allowed_redirect_hosts' ) ); } + + /** + * @ticket 27152 + */ + public function test_raw_referer_empty( ) { + $this->assertFalse( wp_get_raw_referer() ); + } + + /** + * @ticket 27152 + */ + public function test_raw_referer( ) { + $_SERVER['HTTP_REFERER'] = addslashes( 'http://example.com/foo?bar' ); + $this->assertSame( 'http://example.com/foo?bar', wp_get_raw_referer() ); + } + + /** + * @ticket 27152 + */ + public function test_raw_referer_from_request( ) { + $_REQUEST['_wp_http_referer'] = addslashes( 'http://foo.bar/baz' ); + $this->assertSame( 'http://foo.bar/baz', wp_get_raw_referer() ); + } + + /** + * @ticket 27152 + */ + public function test_raw_referer_both( ) { + $_SERVER['HTTP_REFERER'] = addslashes( 'http://example.com/foo?bar' ); + $_REQUEST['_wp_http_referer'] = addslashes( 'http://foo.bar/baz' ); + $this->assertSame( 'http://foo.bar/baz', wp_get_raw_referer() ); + } }