Make WordPress Core


Ignore:
Timestamp:
06/21/2013 06:12:17 AM (11 years ago)
Author:
nacin
Message:

Better validation of the URL used in core HTTP requests.

Merges [24480] to the 3.5 branch.

Location:
branches/3.5
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • branches/3.5

  • branches/3.5/wp-includes/http.php

    r21988 r24481  
    312312    return false;
    313313}
     314
     315/**
     316 * Validate a URL for safe use in the HTTP API.
     317 *
     318 * @since 3.5.2
     319 *
     320 * @return mixed URL or false on failure.
     321 */
     322function wp_http_validate_url( $url ) {
     323    $url = esc_url_raw( $url, array( 'http', 'https' ) );
     324    if ( ! $url )
     325        return false;
     326
     327    $parsed_url = @parse_url( $url );
     328    if ( ! $parsed_url )
     329        return false;
     330
     331    if ( isset( $parsed_url['user'] ) || isset( $parsed_url['pass'] ) )
     332        return false;
     333
     334    if ( false !== strpos( $parsed_url['host'], ':' ) )
     335        return false;
     336
     337    $parsed_home = @parse_url( get_option( 'home' ) );
     338
     339    $same_host = strtolower( $parsed_home['host'] ) === strtolower( $parsed_url['host'] );
     340
     341    if ( ! $same_host ) {
     342        $host = trim( $parsed_url['host'], '.' );
     343        if ( preg_match( '#^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$#', $host ) ) {
     344            $ip = $host;
     345        } else {
     346            $ip = gethostbyname( $host );
     347            if ( $ip === $host ) // Error condition for gethostbyname()
     348                $ip = false;
     349        }
     350        if ( $ip ) {
     351            if ( '127.0.0.1' === $ip )
     352                return false;
     353            $parts = array_map( 'intval', explode( '.', $ip ) );
     354            if ( 10 === $parts[0] )
     355                return false;
     356            if ( 172 === $parts[0] && 16 <= $parts[1] && 31 >= $parts[1] )
     357                return false;
     358            if ( 192 === $parts[0] && 168 === $parts[1] )
     359                return false;
     360        }
     361    }
     362
     363    if ( empty( $parsed_url['port'] ) )
     364        return $url;
     365
     366    $port = $parsed_url['port'];
     367    if ( 80 === $port || 443 === $port || 8080 === $port )
     368        return $url;
     369
     370    if ( $parsed_home && $same_host && $parsed_home['port'] === $port )
     371        return $url;
     372
     373    return false;
     374}
Note: See TracChangeset for help on using the changeset viewer.