CVE-2017-9066: Server-Side Request Forgery (SSRF) (CWE-918)
value: In WordPress before 4.7.5, there is insufficient redirect validation in the HTTP class, leading to SSRF.
CWE description: The web server receives a URL or similar request from an upstream component and retrieves the contents of this URL, but it does not sufficiently ensure that the request is being sent to the expected destination.
CVSS v3 base score: 8.6
Published: 2017-05-18T14:29Z
Repository: https://github.com/WordPress/WordPress
Language: PHP
Files changed: wp-includes/class-http.php, wp-includes/version.php
Commit date: 2017-05-16 08:38:42 +0000
Commit message: Improve redirect handling

Built from https://develop.svn.wordpress.org/trunk@40689


git-svn-id: http://core.svn.wordpress.org/trunk@40552 1a063a9b-81f0-0310-95a4-ce76da25c4cd

Diff: diff --git a/wp-includes/class-http.php b/wp-includes/class-http.php
index b9f5ab50fba..abee7aa0a53 100644
--- a/wp-includes/class-http.php
+++ b/wp-includes/class-http.php
@@ -304,10 +304,15 @@ class WP_Http {
 		);
 
 		// Ensure redirects follow browser behaviour.
 		$options['hooks']->register( 'requests.before_redirect', array( get_class(), 'browser_redirect_compatibility' ) );
 
+		// Validate redirected URLs.
+		if ( function_exists( 'wp_kses_bad_protocol' ) && $r['reject_unsafe_urls'] ) {
+			$options['hooks']->register( 'requests.before_redirect', array( get_class(), 'validate_redirects' ) );
+		}
+
 		if ( $r['stream'] ) {
 			$options['filename'] = $r['filename'];
 		}
 		if ( empty( $r['redirection'] ) ) {
 			$options['follow_redirects'] = false;
@@ -464,10 +469,24 @@ class WP_Http {
 		if ( $original->status_code === 302 ) {
 			$options['type'] = Requests::GET;
 		}
 	}
 
+	/**
+	 * Validate redirected URLs.
+	 *
+	 * @since 4.7.5
+	 *
+	 * @throws Requests_Exception On unsuccessful URL validation
+	 * @param string $location URL to redirect to.
+	 */
+	public static function validate_redirects( $location ) {
+		if ( ! wp_http_validate_url( $location ) ) {
+			throw new Requests_Exception( __('A valid URL was not provided.'), 'wp_http.redirect_failed_validation' );
+		}
+	}
+
 	/**
 	 * Tests which transports are capable of supporting the request.
 	 *
 	 * @since 3.2.0
 	 * @access public
diff --git a/wp-includes/version.php b/wp-includes/version.php
index 7cf6b4c2b07..9b17c304678 100644
--- a/wp-includes/version.php
+++ b/wp-includes/version.php
@@ -2,11 +2,11 @@
 /**
  * The WordPress version string
  *
  * @global string $wp_version
  */
-$wp_version = '4.8-beta1-40677';
+$wp_version = '4.8-beta1-40689';
 
 /**
  * Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.
  *
  * @global int $wp_db_version

Vulnerable code: $wp_version = '4.8-beta1-40677';
Fixed code: 		// Validate redirected URLs.
		if ( function_exists( 'wp_kses_bad_protocol' ) && $r['reject_unsafe_urls'] ) {
			$options['hooks']->register( 'requests.before_redirect', array( get_class(), 'validate_redirects' ) );
		}

	/**
	 * Validate redirected URLs.
	 *
	 * @since 4.7.5
	 *
	 * @throws Requests_Exception On unsuccessful URL validation
	 * @param string $location URL to redirect to.
	 */
	public static function validate_redirects( $location ) {
		if ( ! wp_http_validate_url( $location ) ) {
			throw new Requests_Exception( __('A valid URL was not provided.'), 'wp_http.redirect_failed_validation' );
		}
	}

$wp_version = '4.8-beta1-40689';