From c55bdebaf3487140837cb83bfcbd44d4695b926e Mon Sep 17 00:00:00 2001 From: ryan Date: Thu, 7 Feb 2008 18:23:51 +0000 Subject: [PATCH] wp_safe_redirect() for 2.0. Props markjaquith and snakefoot. fixes #4606 for 2.0 git-svn-id: http://svn.automattic.com/wordpress/branches/2.0@6751 1a063a9b-81f0-0310-95a4-ce76da25c4cd --- wp-includes/pluggable-functions.php | 57 +++++++++++++++++++++++++---- wp-login.php | 4 +- wp-pass.php | 2 +- 3 files changed, 53 insertions(+), 10 deletions(-) diff --git a/wp-includes/pluggable-functions.php b/wp-includes/pluggable-functions.php index 944c0b2efb..63c47ee857 100644 --- a/wp-includes/pluggable-functions.php +++ b/wp-includes/pluggable-functions.php @@ -259,7 +259,31 @@ if ( !function_exists('wp_redirect') ) : function wp_redirect($location, $status = 302) { global $is_IIS; + $location = apply_filters('wp_redirect', $location, $status); + + if ( !$location ) // allows the wp_redirect filter to cancel a redirect + return false; + + $location = wp_sanitize_redirect($location); + + if ( $is_IIS ) { + header("Refresh: 0;url=$location"); + } else { + if ( php_sapi_name() != 'cgi-fcgi' ) + status_header($status); // This causes problems on IIS and some FastCGI setups + header("Location: $location"); + } +} +endif; + +if ( !function_exists('wp_sanitize_redirect') ) : +/** +* sanitizes a URL for use in a redirect +* @return string redirect-sanitized URL +**/ +function wp_sanitize_redirect($location) { $location = preg_replace('|[^a-z0-9-~+_.?#=&;,/:%]|i', '', $location); + $location = wp_kses_no_null($location); // remove %0d and %0a from location $strip = array('%0d', '%0a'); @@ -273,14 +297,33 @@ function wp_redirect($location, $status = 302) { } } } + return $location; +} +endif; - if ( $is_IIS ) { - header("Refresh: 0;url=$location"); - } else { - if ( php_sapi_name() != 'cgi-fcgi' ) - status_header($status); // This causes problems on IIS and some FastCGI setups - header("Location: $location"); - } +if ( !function_exists('wp_safe_redirect') ) : +/** +* performs a safe (local) redirect, using wp_redirect() +* @return void +**/ +function wp_safe_redirect($location, $status = 302) { + + // Need to look at the URL the way it will end up in wp_redirect() + $location = wp_sanitize_redirect($location); + + // browsers will assume 'http' is your protocol, and will obey a redirect to a URL starting with '//' + if ( substr($location, 0, 2) == '//' ) + $location = 'http:' . $location; + + $lp = parse_url($location); + $wpp = parse_url(get_option('home')); + + $allowed_hosts = (array) apply_filters('allowed_redirect_hosts', array($wpp['host'])); + + if ( isset($lp['host']) && ( !in_array($lp['host'], $allowed_hosts) && $lp['host'] != strtolower($wpp['host'])) ) + $location = get_option('siteurl') . '/wp-admin/'; + + wp_redirect($location, $status); } endif; diff --git a/wp-login.php b/wp-login.php index 4e2a129f36..7d13ef3bd6 100644 --- a/wp-login.php +++ b/wp-login.php @@ -29,7 +29,7 @@ case 'logout': if ( isset($_REQUEST['redirect_to']) ) $redirect_to = $_REQUEST['redirect_to']; - wp_redirect($redirect_to); + wp_safe_redirect($redirect_to); exit(); break; @@ -198,7 +198,7 @@ default: if ( !$using_cookie ) wp_setcookie($user_login, $user_pass, false, '', '', $rememberme); do_action('wp_login', $user_login); - wp_redirect($redirect_to); + wp_safe_redirect($redirect_to); exit; } else { if ( $using_cookie ) diff --git a/wp-pass.php b/wp-pass.php index e1cb4e055e..709a63b07f 100644 --- a/wp-pass.php +++ b/wp-pass.php @@ -7,5 +7,5 @@ if ( get_magic_quotes_gpc() ) // 10 days setcookie('wp-postpass_' . COOKIEHASH, $_POST['post_password'], time() + 864000, COOKIEPATH); -wp_redirect(wp_get_referer()); +wp_safe_redirect(wp_get_referer()); ?> \ No newline at end of file