Better validation of the URL used in core HTTP requests.
git-svn-id: http://core.svn.wordpress.org/trunk@24480 1a063a9b-81f0-0310-95a4-ce76da25c4cd
This commit is contained in:
parent
c0c884b522
commit
96ee267343
|
@ -183,6 +183,7 @@ class WP_Importer {
|
||||||
|
|
||||||
$headers = array();
|
$headers = array();
|
||||||
$args = array();
|
$args = array();
|
||||||
|
$args['reject_unsafe_urls'] = true;
|
||||||
if ( true === $head )
|
if ( true === $head )
|
||||||
$args['method'] = 'HEAD';
|
$args['method'] = 'HEAD';
|
||||||
if ( !empty( $username ) && !empty( $password ) )
|
if ( !empty( $username ) && !empty( $password ) )
|
||||||
|
|
|
@ -497,7 +497,7 @@ function download_url( $url, $timeout = 300 ) {
|
||||||
if ( ! $tmpfname )
|
if ( ! $tmpfname )
|
||||||
return new WP_Error('http_no_file', __('Could not create Temporary file.'));
|
return new WP_Error('http_no_file', __('Could not create Temporary file.'));
|
||||||
|
|
||||||
$response = wp_remote_get( $url, array( 'timeout' => $timeout, 'stream' => true, 'filename' => $tmpfname ) );
|
$response = wp_remote_get( $url, array( 'timeout' => $timeout, 'stream' => true, 'filename' => $tmpfname, 'reject_unsafe_urls' => true ) );
|
||||||
|
|
||||||
if ( is_wp_error( $response ) ) {
|
if ( is_wp_error( $response ) ) {
|
||||||
unlink( $tmpfname );
|
unlink( $tmpfname );
|
||||||
|
|
|
@ -66,7 +66,11 @@ class WP_SimplePie_File extends SimplePie_File {
|
||||||
$this->method = SIMPLEPIE_FILE_SOURCE_REMOTE;
|
$this->method = SIMPLEPIE_FILE_SOURCE_REMOTE;
|
||||||
|
|
||||||
if ( preg_match('/^http(s)?:\/\//i', $url) ) {
|
if ( preg_match('/^http(s)?:\/\//i', $url) ) {
|
||||||
$args = array( 'timeout' => $this->timeout, 'redirection' => $this->redirects);
|
$args = array(
|
||||||
|
'timeout' => $this->timeout,
|
||||||
|
'redirection' => $this->redirects,
|
||||||
|
'reject_unsafe_urls' => true,
|
||||||
|
);
|
||||||
|
|
||||||
if ( !empty($this->headers) )
|
if ( !empty($this->headers) )
|
||||||
$args['headers'] = $this->headers;
|
$args['headers'] = $this->headers;
|
||||||
|
@ -85,10 +89,8 @@ class WP_SimplePie_File extends SimplePie_File {
|
||||||
$this->status_code = wp_remote_retrieve_response_code( $res );
|
$this->status_code = wp_remote_retrieve_response_code( $res );
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if ( ! file_exists($url) || ( ! $this->body = file_get_contents($url) ) ) {
|
$this->error = '';
|
||||||
$this->error = 'file_get_contents could not read the file';
|
$this->success = false;
|
||||||
$this->success = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -86,7 +86,8 @@ class WP_Http {
|
||||||
'timeout' => apply_filters( 'http_request_timeout', 5),
|
'timeout' => apply_filters( 'http_request_timeout', 5),
|
||||||
'redirection' => apply_filters( 'http_request_redirection_count', 5),
|
'redirection' => apply_filters( 'http_request_redirection_count', 5),
|
||||||
'httpversion' => apply_filters( 'http_request_version', '1.0'),
|
'httpversion' => apply_filters( 'http_request_version', '1.0'),
|
||||||
'user-agent' => apply_filters( 'http_headers_useragent', 'WordPress/' . $wp_version . '; ' . get_bloginfo( 'url' ) ),
|
'user-agent' => apply_filters( 'http_headers_useragent', 'WordPress/' . $wp_version . '; ' . get_bloginfo( 'url' ) ),
|
||||||
|
'reject_unsafe_urls' => apply_filters( 'http_request_reject_unsafe_urls', false ),
|
||||||
'blocking' => true,
|
'blocking' => true,
|
||||||
'headers' => array(),
|
'headers' => array(),
|
||||||
'cookies' => array(),
|
'cookies' => array(),
|
||||||
|
@ -118,7 +119,11 @@ class WP_Http {
|
||||||
if ( false !== $pre )
|
if ( false !== $pre )
|
||||||
return $pre;
|
return $pre;
|
||||||
|
|
||||||
$arrURL = parse_url( $url );
|
if ( $r['reject_unsafe_urls'] )
|
||||||
|
$url = wp_http_validate_url( $url );
|
||||||
|
$url = wp_kses_bad_protocol( $url, array( 'http', 'https', 'ssl' ) );
|
||||||
|
|
||||||
|
$arrURL = @parse_url( $url );
|
||||||
|
|
||||||
if ( empty( $url ) || empty( $arrURL['scheme'] ) )
|
if ( empty( $url ) || empty( $arrURL['scheme'] ) )
|
||||||
return new WP_Error('http_request_failed', __('A valid URL was not provided.'));
|
return new WP_Error('http_request_failed', __('A valid URL was not provided.'));
|
||||||
|
@ -1146,6 +1151,8 @@ class WP_Http_Curl {
|
||||||
// The option doesn't work with safe mode or when open_basedir is set, and there's a
|
// The option doesn't work with safe mode or when open_basedir is set, and there's a
|
||||||
// bug #17490 with redirected POST requests, so handle redirections outside Curl.
|
// bug #17490 with redirected POST requests, so handle redirections outside Curl.
|
||||||
curl_setopt( $handle, CURLOPT_FOLLOWLOCATION, false );
|
curl_setopt( $handle, CURLOPT_FOLLOWLOCATION, false );
|
||||||
|
if ( defined( 'CURLOPT_PROTOCOLS' ) ) // PHP 5.2.10 / cURL 7.19.4
|
||||||
|
curl_setopt( $handle, CURLOPT_PROTOCOLS, CURLPROTO_HTTP | CURLPROTO_HTTPS );
|
||||||
|
|
||||||
switch ( $r['method'] ) {
|
switch ( $r['method'] ) {
|
||||||
case 'HEAD':
|
case 'HEAD':
|
||||||
|
|
|
@ -113,7 +113,7 @@ class WP_oEmbed {
|
||||||
$providers = array();
|
$providers = array();
|
||||||
|
|
||||||
// Fetch URL content
|
// Fetch URL content
|
||||||
if ( $html = wp_remote_retrieve_body( wp_remote_get( $url ) ) ) {
|
if ( $html = wp_remote_retrieve_body( wp_remote_get( $url, array( 'reject_unsafe_urls' => true ) ) ) ) {
|
||||||
|
|
||||||
// <link> types that contain oEmbed provider URLs
|
// <link> types that contain oEmbed provider URLs
|
||||||
$linktypes = apply_filters( 'oembed_linktypes', array(
|
$linktypes = apply_filters( 'oembed_linktypes', array(
|
||||||
|
@ -195,7 +195,7 @@ class WP_oEmbed {
|
||||||
*/
|
*/
|
||||||
function _fetch_with_format( $provider_url_with_args, $format ) {
|
function _fetch_with_format( $provider_url_with_args, $format ) {
|
||||||
$provider_url_with_args = add_query_arg( 'format', $format, $provider_url_with_args );
|
$provider_url_with_args = add_query_arg( 'format', $format, $provider_url_with_args );
|
||||||
$response = wp_remote_get( $provider_url_with_args );
|
$response = wp_remote_get( $provider_url_with_args, array( 'reject_unsafe_urls' => true ) );
|
||||||
if ( 501 == wp_remote_retrieve_response_code( $response ) )
|
if ( 501 == wp_remote_retrieve_response_code( $response ) )
|
||||||
return new WP_Error( 'not-implemented' );
|
return new WP_Error( 'not-implemented' );
|
||||||
if ( ! $body = wp_remote_retrieve_body( $response ) )
|
if ( ! $body = wp_remote_retrieve_body( $response ) )
|
||||||
|
|
|
@ -5396,7 +5396,8 @@ class wp_xmlrpc_server extends IXR_Server {
|
||||||
sleep(1);
|
sleep(1);
|
||||||
|
|
||||||
// Let's check the remote site
|
// Let's check the remote site
|
||||||
$linea = wp_remote_retrieve_body( wp_remote_get( $pagelinkedfrom, array( 'timeout' => 10, 'redirection' => 0 ) ) );
|
$linea = wp_remote_retrieve_body( wp_remote_get( $pagelinkedfrom, array( 'timeout' => 10, 'redirection' => 0, 'reject_unsafe_urls' => true ) ) );
|
||||||
|
|
||||||
if ( !$linea )
|
if ( !$linea )
|
||||||
return $this->pingback_error( 16, __( 'The source URL does not exist.' ) );
|
return $this->pingback_error( 16, __( 'The source URL does not exist.' ) );
|
||||||
|
|
||||||
|
|
|
@ -1658,7 +1658,7 @@ function discover_pingback_server_uri( $url, $deprecated = '' ) {
|
||||||
if ( 0 === strpos($url, $uploads_dir['baseurl']) )
|
if ( 0 === strpos($url, $uploads_dir['baseurl']) )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
$response = wp_remote_head( $url, array( 'timeout' => 2, 'httpversion' => '1.0' ) );
|
$response = wp_remote_head( $url, array( 'timeout' => 2, 'httpversion' => '1.0', 'reject_unsafe_urls' => true ) );
|
||||||
|
|
||||||
if ( is_wp_error( $response ) )
|
if ( is_wp_error( $response ) )
|
||||||
return false;
|
return false;
|
||||||
|
@ -1671,7 +1671,7 @@ function discover_pingback_server_uri( $url, $deprecated = '' ) {
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Now do a GET since we're going to look in the html headers (and we're sure it's not a binary file)
|
// Now do a GET since we're going to look in the html headers (and we're sure it's not a binary file)
|
||||||
$response = wp_remote_get( $url, array( 'timeout' => 2, 'httpversion' => '1.0' ) );
|
$response = wp_remote_get( $url, array( 'timeout' => 2, 'httpversion' => '1.0', 'reject_unsafe_urls' => true ) );
|
||||||
|
|
||||||
if ( is_wp_error( $response ) )
|
if ( is_wp_error( $response ) )
|
||||||
return false;
|
return false;
|
||||||
|
@ -1906,6 +1906,7 @@ function trackback($trackback_url, $title, $excerpt, $ID) {
|
||||||
|
|
||||||
$options = array();
|
$options = array();
|
||||||
$options['timeout'] = 4;
|
$options['timeout'] = 4;
|
||||||
|
$options['reject_unsafe_urls'] = true;
|
||||||
$options['body'] = array(
|
$options['body'] = array(
|
||||||
'title' => $title,
|
'title' => $title,
|
||||||
'url' => get_permalink($ID),
|
'url' => get_permalink($ID),
|
||||||
|
@ -1953,62 +1954,13 @@ function weblog_ping($server = '', $path = '') {
|
||||||
* Default filter attached to pingback_ping_source_uri to validate the pingback's Source URI
|
* Default filter attached to pingback_ping_source_uri to validate the pingback's Source URI
|
||||||
*
|
*
|
||||||
* @since 3.5.1
|
* @since 3.5.1
|
||||||
|
* @see wp_http_validate_url()
|
||||||
*
|
*
|
||||||
* @param string $source_uri
|
* @param string $source_uri
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
function pingback_ping_source_uri( $source_uri ) {
|
function pingback_ping_source_uri( $source_uri ) {
|
||||||
$uri = esc_url_raw( $source_uri, array( 'http', 'https' ) );
|
return (string) wp_http_validate_url( $source_uri );
|
||||||
if ( ! $uri )
|
|
||||||
return '';
|
|
||||||
|
|
||||||
$parsed_url = @parse_url( $uri );
|
|
||||||
if ( ! $parsed_url )
|
|
||||||
return '';
|
|
||||||
|
|
||||||
if ( isset( $parsed_url['user'] ) || isset( $parsed_url['pass'] ) )
|
|
||||||
return '';
|
|
||||||
|
|
||||||
if ( false !== strpos( $parsed_url['host'], ':' ) )
|
|
||||||
return '';
|
|
||||||
|
|
||||||
$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 '';
|
|
||||||
$parts = array_map( 'intval', explode( '.', $ip ) );
|
|
||||||
if ( 10 === $parts[0] )
|
|
||||||
return '';
|
|
||||||
if ( 172 === $parts[0] && 16 <= $parts[1] && 31 >= $parts[1] )
|
|
||||||
return '';
|
|
||||||
if ( 192 === $parts[0] && 168 === $parts[1] )
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( empty( $parsed_url['port'] ) )
|
|
||||||
return $uri;
|
|
||||||
|
|
||||||
$port = $parsed_url['port'];
|
|
||||||
if ( 80 === $port || 443 === $port || 8080 === $port )
|
|
||||||
return $uri;
|
|
||||||
|
|
||||||
if ( $parsed_home && $same_host && $parsed_home['port'] === $port )
|
|
||||||
return $uri;
|
|
||||||
|
|
||||||
return '';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -496,6 +496,7 @@ function wp_get_http( $url, $file_path = false, $red = 1 ) {
|
||||||
|
|
||||||
$options = array();
|
$options = array();
|
||||||
$options['redirection'] = 5;
|
$options['redirection'] = 5;
|
||||||
|
$options['reject_unsafe_urls'] = true;
|
||||||
|
|
||||||
if ( false == $file_path )
|
if ( false == $file_path )
|
||||||
$options['method'] = 'HEAD';
|
$options['method'] = 'HEAD';
|
||||||
|
@ -543,7 +544,7 @@ function wp_get_http_headers( $url, $deprecated = false ) {
|
||||||
if ( !empty( $deprecated ) )
|
if ( !empty( $deprecated ) )
|
||||||
_deprecated_argument( __FUNCTION__, '2.7' );
|
_deprecated_argument( __FUNCTION__, '2.7' );
|
||||||
|
|
||||||
$response = wp_remote_head( $url );
|
$response = wp_remote_head( $url, array( 'reject_unsafe_urls' => true ) );
|
||||||
|
|
||||||
if ( is_wp_error( $response ) )
|
if ( is_wp_error( $response ) )
|
||||||
return false;
|
return false;
|
||||||
|
@ -758,6 +759,7 @@ function wp_remote_fopen( $uri ) {
|
||||||
|
|
||||||
$options = array();
|
$options = array();
|
||||||
$options['timeout'] = 10;
|
$options['timeout'] = 10;
|
||||||
|
$options['reject_unsafe_urls'] = true;
|
||||||
|
|
||||||
$response = wp_remote_get( $uri, $options );
|
$response = wp_remote_get( $uri, $options );
|
||||||
|
|
||||||
|
|
|
@ -330,3 +330,64 @@ function send_origin_headers() {
|
||||||
|
|
||||||
return false;
|
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;
|
||||||
|
}
|
||||||
|
|
|
@ -536,7 +536,7 @@ endif;
|
||||||
* @return Snoopy style response
|
* @return Snoopy style response
|
||||||
*/
|
*/
|
||||||
function _fetch_remote_file($url, $headers = "" ) {
|
function _fetch_remote_file($url, $headers = "" ) {
|
||||||
$resp = wp_remote_request($url, array('headers' => $headers, 'timeout' => MAGPIE_FETCH_TIME_OUT));
|
$resp = wp_remote_request($url, array('headers' => $headers, 'timeout' => MAGPIE_FETCH_TIME_OUT, 'reject_unsafe_urls' => true ));
|
||||||
if ( is_wp_error($resp) ) {
|
if ( is_wp_error($resp) ) {
|
||||||
$error = array_shift($resp->errors);
|
$error = array_shift($resp->errors);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue