wp_validate_redirect()WP 2.8.1

Checks the specified URL for the possibility of using it for redirection.

By default, only URLs of the current site are allowed (internal URL addresses).

If the specified URL fails the check, the function will return the value of the second parameter $default.

What the function does:

  1. Adds http: protocol for links without a protocol (//)
  2. Checks the protocol, only http and https are allowed.
  3. Checks the other components of the URL.
  4. Compares the domain of the specified URL with the whitelist of domains to which redirection is allowed. By default, the whitelist contains only the domain of the current site. The whitelist can be expanded through the filter allowed_redirect_hosts.

To sanitize the redirect link, use wp_sanitize_redirect()

Pluggable function — this function can be replaced from a plugin. It means that this function is defined (works) only after all plugins are loaded (included), but before this moment this function has not defined. Therefore, you cannot call this and all functions depended on this function directly from a plugin code. They need to be called on plugins_loaded hook or later, for example on init hook.

Function replacement (override) — in must-use or regular plugin you can create a function with the same name, then it will replace this function.

1 time — 0.003549 sec (very slow) | 50000 times — 2.44 sec (fast) | PHP 7.0.32, WP 5.1.1
Hooks from the function

Returns

String. The specified URL address if it passes the check or the value of the $default parameter.

Usage

wp_validate_redirect( $location, $default );
$location(string) (required)
URL to check.
$default(string)
Default URL that the function will return if the URL from the $location parameter fails the check.
Default: ''

Examples

0

#1 Demo

It is assumed that the function was launched at example.com.

echo wp_validate_redirect( 'http://foo.bar' );                    //> ''
echo wp_validate_redirect( 'http://foo.bar', 'http://my.site' );  //> http://my.site
echo wp_validate_redirect( '//example.com/foo' );                 //> http://example.ru/foo
echo wp_validate_redirect( 'https://example.com/foo' );           //> https://example.ru/foo

Changelog

Since 2.8.1 Introduced.

wp_validate_redirect() code WP 6.9.1

function wp_validate_redirect( $location, $fallback_url = '' ) {
	$location = wp_sanitize_redirect( trim( $location, " \t\n\r\0\x08\x0B" ) );
	// Browsers will assume 'http' is your protocol, and will obey a redirect to a URL starting with '//'.
	if ( str_starts_with( $location, '//' ) ) {
		$location = 'http:' . $location;
	}

	/*
	 * In PHP 5 parse_url() may fail if the URL query part contains 'http://'.
	 * See https://bugs.php.net/bug.php?id=38143
	 */
	$cut  = strpos( $location, '?' );
	$test = $cut ? substr( $location, 0, $cut ) : $location;

	$lp = parse_url( $test );

	// Give up if malformed URL.
	if ( false === $lp ) {
		return $fallback_url;
	}

	// Allow only 'http' and 'https' schemes. No 'data:', etc.
	if ( isset( $lp['scheme'] ) && ! ( 'http' === $lp['scheme'] || 'https' === $lp['scheme'] ) ) {
		return $fallback_url;
	}

	if ( ! isset( $lp['host'] ) && ! empty( $lp['path'] ) && '/' !== $lp['path'][0] ) {
		$path = '';
		if ( ! empty( $_SERVER['REQUEST_URI'] ) ) {
			$path = dirname( parse_url( 'http://placeholder' . $_SERVER['REQUEST_URI'], PHP_URL_PATH ) . '?' );
			$path = wp_normalize_path( $path );
		}
		$location = '/' . ltrim( $path . '/', '/' ) . $location;
	}

	/*
	 * Reject if certain components are set but host is not.
	 * This catches URLs like https:host.com for which parse_url() does not set the host field.
	 */
	if ( ! isset( $lp['host'] ) && ( isset( $lp['scheme'] ) || isset( $lp['user'] ) || isset( $lp['pass'] ) || isset( $lp['port'] ) ) ) {
		return $fallback_url;
	}

	// Reject malformed components parse_url() can return on odd inputs.
	foreach ( array( 'user', 'pass', 'host' ) as $component ) {
		if ( isset( $lp[ $component ] ) && strpbrk( $lp[ $component ], ':/?#@' ) ) {
			return $fallback_url;
		}
	}

	$wpp = parse_url( home_url() );

	/**
	 * Filters the list of allowed hosts to redirect to.
	 *
	 * @since 2.3.0
	 *
	 * @param string[] $hosts An array of allowed host names.
	 * @param string   $host  The host name of the redirect destination; empty string if not set.
	 */
	$allowed_hosts = (array) apply_filters( 'allowed_redirect_hosts', array( $wpp['host'] ), isset( $lp['host'] ) ? $lp['host'] : '' );

	if ( isset( $lp['host'] ) && ( ! in_array( $lp['host'], $allowed_hosts, true ) && strtolower( $wpp['host'] ) !== $lp['host'] ) ) {
		$location = $fallback_url;
	}

	return $location;
}