WordPress.org

Make WordPress Core

Changeset 24480


Ignore:
Timestamp:
06/21/2013 06:07:47 AM (8 years ago)
Author:
nacin
Message:

Better validation of the URL used in core HTTP requests.

Location:
trunk
Files:
10 edited

Legend:

Unmodified
Added
Removed
  • trunk/wp-admin/includes/class-wp-importer.php

    r22108 r24480  
    184184        $headers = array();
    185185        $args = array();
     186        $args['reject_unsafe_urls'] = true;
    186187        if ( true === $head )
    187188            $args['method'] = 'HEAD';
  • trunk/wp-admin/includes/file.php

    r24463 r24480  
    498498        return new WP_Error('http_no_file', __('Could not create Temporary file.'));
    499499
    500     $response = wp_remote_get( $url, array( 'timeout' => $timeout, 'stream' => true, 'filename' => $tmpfname ) );
     500    $response = wp_remote_get( $url, array( 'timeout' => $timeout, 'stream' => true, 'filename' => $tmpfname, 'reject_unsafe_urls' => true ) );
    501501
    502502    if ( is_wp_error( $response ) ) {
  • trunk/wp-includes/class-feed.php

    r22811 r24480  
    6767
    6868        if ( preg_match('/^http(s)?:\/\//i', $url) ) {
    69             $args = array( 'timeout' => $this->timeout, 'redirection' => $this->redirects);
     69            $args = array(
     70                'timeout' => $this->timeout,
     71                'redirection' => $this->redirects,
     72                'reject_unsafe_urls' => true,
     73            );
    7074
    7175            if ( !empty($this->headers) )
     
    8690            }
    8791        } else {
    88             if ( ! file_exists($url) || ( ! $this->body = file_get_contents($url) ) ) {
    89                 $this->error = 'file_get_contents could not read the file';
    90                 $this->success = false;
    91             }
     92            $this->error = '';
     93            $this->success = false;
    9294        }
    9395    }
  • trunk/wp-includes/class-http.php

    r24303 r24480  
    8787            'redirection' => apply_filters( 'http_request_redirection_count', 5),
    8888            'httpversion' => apply_filters( 'http_request_version', '1.0'),
    89             'user-agent' => apply_filters( 'http_headers_useragent', 'WordPress/' . $wp_version . '; ' . get_bloginfo( 'url' )  ),
     89            'user-agent' => apply_filters( 'http_headers_useragent', 'WordPress/' . $wp_version . '; ' . get_bloginfo( 'url' ) ),
     90            'reject_unsafe_urls' => apply_filters( 'http_request_reject_unsafe_urls', false ),
    9091            'blocking' => true,
    9192            'headers' => array(),
     
    119120            return $pre;
    120121
    121         $arrURL = parse_url( $url );
     122        if ( $r['reject_unsafe_urls'] )
     123            $url = wp_http_validate_url( $url );
     124        $url = wp_kses_bad_protocol( $url, array( 'http', 'https', 'ssl' ) );
     125
     126        $arrURL = @parse_url( $url );
    122127
    123128        if ( empty( $url ) || empty( $arrURL['scheme'] ) )
     
    11471152        // bug #17490 with redirected POST requests, so handle redirections outside Curl.
    11481153        curl_setopt( $handle, CURLOPT_FOLLOWLOCATION, false );
     1154        if ( defined( 'CURLOPT_PROTOCOLS' ) ) // PHP 5.2.10 / cURL 7.19.4
     1155            curl_setopt( $handle, CURLOPT_PROTOCOLS, CURLPROTO_HTTP | CURLPROTO_HTTPS );
    11491156
    11501157        switch ( $r['method'] ) {
  • trunk/wp-includes/class-oembed.php

    r24470 r24480  
    114114
    115115        // Fetch URL content
    116         if ( $html = wp_remote_retrieve_body( wp_remote_get( $url ) ) ) {
     116        if ( $html = wp_remote_retrieve_body( wp_remote_get( $url, array( 'reject_unsafe_urls' => true ) ) ) ) {
    117117
    118118            // <link> types that contain oEmbed provider URLs
     
    196196    function _fetch_with_format( $provider_url_with_args, $format ) {
    197197        $provider_url_with_args = add_query_arg( 'format', $format, $provider_url_with_args );
    198         $response = wp_remote_get( $provider_url_with_args );
     198        $response = wp_remote_get( $provider_url_with_args, array( 'reject_unsafe_urls' => true ) );
    199199        if ( 501 == wp_remote_retrieve_response_code( $response ) )
    200200            return new WP_Error( 'not-implemented' );
  • trunk/wp-includes/class-wp-xmlrpc-server.php

    r24382 r24480  
    53975397
    53985398        // Let's check the remote site
    5399         $linea = wp_remote_retrieve_body( wp_remote_get( $pagelinkedfrom, array( 'timeout' => 10, 'redirection' => 0 ) ) );
     5399        $linea = wp_remote_retrieve_body( wp_remote_get( $pagelinkedfrom, array( 'timeout' => 10, 'redirection' => 0, 'reject_unsafe_urls' => true ) ) );
     5400
    54005401        if ( !$linea )
    54015402            return $this->pingback_error( 16, __( 'The source URL does not exist.' ) );
  • trunk/wp-includes/comment.php

    r24301 r24480  
    16591659        return false;
    16601660
    1661     $response = wp_remote_head( $url, array( 'timeout' => 2, 'httpversion' => '1.0' ) );
     1661    $response = wp_remote_head( $url, array( 'timeout' => 2, 'httpversion' => '1.0', 'reject_unsafe_urls' => true ) );
    16621662
    16631663    if ( is_wp_error( $response ) )
     
    16721672
    16731673    // Now do a GET since we're going to look in the html headers (and we're sure it's not a binary file)
    1674     $response = wp_remote_get( $url, array( 'timeout' => 2, 'httpversion' => '1.0' ) );
     1674    $response = wp_remote_get( $url, array( 'timeout' => 2, 'httpversion' => '1.0', 'reject_unsafe_urls' => true ) );
    16751675
    16761676    if ( is_wp_error( $response ) )
     
    19071907    $options = array();
    19081908    $options['timeout'] = 4;
     1909    $options['reject_unsafe_urls'] = true;
    19091910    $options['body'] = array(
    19101911        'title' => $title,
     
    19541955 *
    19551956 * @since 3.5.1
     1957 * @see wp_http_validate_url()
    19561958 *
    19571959 * @param string $source_uri
     
    19591961 */
    19601962function pingback_ping_source_uri( $source_uri ) {
    1961     $uri = esc_url_raw( $source_uri, array( 'http', 'https' ) );
    1962     if ( ! $uri )
    1963         return '';
    1964 
    1965     $parsed_url = @parse_url( $uri );
    1966     if ( ! $parsed_url )
    1967         return '';
    1968 
    1969     if ( isset( $parsed_url['user'] ) || isset( $parsed_url['pass'] ) )
    1970         return '';
    1971 
    1972     if ( false !== strpos( $parsed_url['host'], ':' ) )
    1973         return '';
    1974 
    1975     $parsed_home = @parse_url( get_option( 'home' ) );
    1976 
    1977     $same_host = strtolower( $parsed_home['host'] ) === strtolower( $parsed_url['host'] );
    1978 
    1979     if ( ! $same_host ) {
    1980         $host = trim( $parsed_url['host'], '.' );
    1981         if ( preg_match( '#^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$#', $host ) ) {
    1982             $ip = $host;
    1983         } else {
    1984             $ip = gethostbyname( $host );
    1985             if ( $ip === $host ) // Error condition for gethostbyname()
    1986                 $ip = false;
    1987         }
    1988         if ( $ip ) {
    1989             if ( '127.0.0.1' === $ip )
    1990                 return '';
    1991             $parts = array_map( 'intval', explode( '.', $ip ) );
    1992             if ( 10 === $parts[0] )
    1993                 return '';
    1994             if ( 172 === $parts[0] && 16 <= $parts[1] && 31 >= $parts[1] )
    1995                 return '';
    1996             if ( 192 === $parts[0] && 168 === $parts[1] )
    1997                 return '';
    1998         }
    1999     }
    2000 
    2001     if ( empty( $parsed_url['port'] ) )
    2002         return $uri;
    2003 
    2004     $port = $parsed_url['port'];
    2005     if ( 80 === $port || 443 === $port || 8080 === $port )
    2006         return $uri;
    2007 
    2008     if ( $parsed_home && $same_host && $parsed_home['port'] === $port )
    2009         return $uri;
    2010 
    2011     return '';
     1963    return (string) wp_http_validate_url( $source_uri );
    20121964}
    20131965
  • trunk/wp-includes/functions.php

    r24444 r24480  
    497497    $options = array();
    498498    $options['redirection'] = 5;
     499    $options['reject_unsafe_urls'] = true;
    499500
    500501    if ( false == $file_path )
     
    544545        _deprecated_argument( __FUNCTION__, '2.7' );
    545546
    546     $response = wp_remote_head( $url );
     547    $response = wp_remote_head( $url, array( 'reject_unsafe_urls' => true ) );
    547548
    548549    if ( is_wp_error( $response ) )
     
    759760    $options = array();
    760761    $options['timeout'] = 10;
     762    $options['reject_unsafe_urls'] = true;
    761763
    762764    $response = wp_remote_get( $uri, $options );
  • trunk/wp-includes/http.php

    r24250 r24480  
    331331    return false;
    332332}
     333
     334/**
     335 * Validate a URL for safe use in the HTTP API.
     336 *
     337 * @since 3.5.2
     338 *
     339 * @return mixed URL or false on failure.
     340 */
     341function wp_http_validate_url( $url ) {
     342    $url = esc_url_raw( $url, array( 'http', 'https' ) );
     343    if ( ! $url )
     344        return false;
     345
     346    $parsed_url = @parse_url( $url );
     347    if ( ! $parsed_url )
     348        return false;
     349
     350    if ( isset( $parsed_url['user'] ) || isset( $parsed_url['pass'] ) )
     351        return false;
     352
     353    if ( false !== strpos( $parsed_url['host'], ':' ) )
     354        return false;
     355
     356    $parsed_home = @parse_url( get_option( 'home' ) );
     357
     358    $same_host = strtolower( $parsed_home['host'] ) === strtolower( $parsed_url['host'] );
     359
     360    if ( ! $same_host ) {
     361        $host = trim( $parsed_url['host'], '.' );
     362        if ( preg_match( '#^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$#', $host ) ) {
     363            $ip = $host;
     364        } else {
     365            $ip = gethostbyname( $host );
     366            if ( $ip === $host ) // Error condition for gethostbyname()
     367                $ip = false;
     368        }
     369        if ( $ip ) {
     370            if ( '127.0.0.1' === $ip )
     371                return false;
     372            $parts = array_map( 'intval', explode( '.', $ip ) );
     373            if ( 10 === $parts[0] )
     374                return false;
     375            if ( 172 === $parts[0] && 16 <= $parts[1] && 31 >= $parts[1] )
     376                return false;
     377            if ( 192 === $parts[0] && 168 === $parts[1] )
     378                return false;
     379        }
     380    }
     381
     382    if ( empty( $parsed_url['port'] ) )
     383        return $url;
     384
     385    $port = $parsed_url['port'];
     386    if ( 80 === $port || 443 === $port || 8080 === $port )
     387        return $url;
     388
     389    if ( $parsed_home && $same_host && $parsed_home['port'] === $port )
     390        return $url;
     391
     392    return false;
     393}
  • trunk/wp-includes/rss.php

    r23191 r24480  
    537537 */
    538538function _fetch_remote_file($url, $headers = "" ) {
    539     $resp = wp_remote_request($url, array('headers' => $headers, 'timeout' => MAGPIE_FETCH_TIME_OUT));
     539    $resp = wp_remote_request($url, array('headers' => $headers, 'timeout' => MAGPIE_FETCH_TIME_OUT, 'reject_unsafe_urls' => true ));
    540540    if ( is_wp_error($resp) ) {
    541541        $error = array_shift($resp->errors);
Note: See TracChangeset for help on using the changeset viewer.