Better validation of the URL used in core HTTP requests.

git-svn-id: https://develop.svn.wordpress.org/trunk@24480 602fd350-edb4-49c9-b593-d223f7449a82
This commit is contained in:
Andrew Nacin
2013-06-21 06:07:47 +00:00
parent 5254ff0e4b
commit dfcf4b5eae
10 changed files with 92 additions and 66 deletions

View File

@@ -330,3 +330,64 @@ function send_origin_headers() {
return false;
}
/**
* Validate a URL for safe use in the HTTP API.
*
* @since 3.5.2
*
* @return mixed URL or false on failure.
*/
function wp_http_validate_url( $url ) {
$url = esc_url_raw( $url, array( 'http', 'https' ) );
if ( ! $url )
return false;
$parsed_url = @parse_url( $url );
if ( ! $parsed_url )
return false;
if ( isset( $parsed_url['user'] ) || isset( $parsed_url['pass'] ) )
return false;
if ( false !== strpos( $parsed_url['host'], ':' ) )
return false;
$parsed_home = @parse_url( get_option( 'home' ) );
$same_host = strtolower( $parsed_home['host'] ) === strtolower( $parsed_url['host'] );
if ( ! $same_host ) {
$host = trim( $parsed_url['host'], '.' );
if ( preg_match( '#^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$#', $host ) ) {
$ip = $host;
} else {
$ip = gethostbyname( $host );
if ( $ip === $host ) // Error condition for gethostbyname()
$ip = false;
}
if ( $ip ) {
if ( '127.0.0.1' === $ip )
return false;
$parts = array_map( 'intval', explode( '.', $ip ) );
if ( 10 === $parts[0] )
return false;
if ( 172 === $parts[0] && 16 <= $parts[1] && 31 >= $parts[1] )
return false;
if ( 192 === $parts[0] && 168 === $parts[1] )
return false;
}
}
if ( empty( $parsed_url['port'] ) )
return $url;
$port = $parsed_url['port'];
if ( 80 === $port || 443 === $port || 8080 === $port )
return $url;
if ( $parsed_home && $same_host && $parsed_home['port'] === $port )
return $url;
return false;
}