WordPress.org

Make WordPress Core


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.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • 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}
Note: See TracChangeset for help on using the changeset viewer.