CVE-2017-6819: Cross-Site Request Forgery (CSRF) (CWE-352)
value: In WordPress before 4.7.3, there is cross-site request forgery (CSRF) in Press This (wp-admin/includes/class-wp-press-this.php), leading to excessive use of server resources. The CSRF can trigger an outbound HTTP request for a large file that is then parsed by Press This.
CWE description: The web application does not, or can not, sufficiently verify whether a well-formed, valid, consistent request was intentionally provided by the user who submitted the request.
CVSS v3 base score: 6.5
Published: 2017-03-12T01:59Z
Repository: https://github.com/WordPress/WordPress
Language: PHP
Files changed: wp-admin/includes/class-wp-press-this.php, wp-includes/version.php
Commit date: 2017-03-06 13:55:41 +0000
Commit message: Press This: Verify intent before fetching in-page resources using Press This.

Props vortfu

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


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

Diff: diff --git a/wp-admin/includes/class-wp-press-this.php b/wp-admin/includes/class-wp-press-this.php
index 273c1ab1f14..bc5724256bd 100644
--- a/wp-admin/includes/class-wp-press-this.php
+++ b/wp-admin/includes/class-wp-press-this.php
@@ -716,11 +716,15 @@ class WP_Press_This {
 			/*
 			 * If no title, _images, _embed, and _meta was passed via $_POST, fetch data from source as fallback,
 			 * making PT fully backward compatible with the older bookmarklet.
 			 */
 			if ( empty( $_POST ) && ! empty( $data['u'] ) ) {
-				$data = $this->source_data_fetch_fallback( $data['u'], $data );
+				if ( isset( $_GET['_wpnonce'] ) && wp_verify_nonce( $_GET['_wpnonce'], 'scan-site' ) ) {
+					$data = $this->source_data_fetch_fallback( $data['u'], $data );
+				} else {
+					$data['errors'] = 'missing nonce';
+				}
 			} else {
 				foreach ( array( '_images', '_embeds' ) as $type ) {
 					if ( empty( $_POST[ $type ] ) ) {
 						continue;
 					}
@@ -1233,11 +1237,11 @@ class WP_Press_This {
 		$embeds = $this->get_embeds( $data );
 
 		$site_data = array(
 			'v' => ! empty( $data['v'] ) ? $data['v'] : '',
 			'u' => ! empty( $data['u'] ) ? $data['u'] : '',
-			'hasData' => ! empty( $data ),
+			'hasData' => ! empty( $data ) && ! isset( $data['errors'] ),
 		);
 
 		if ( ! empty( $images ) ) {
 			$site_data['_images'] = $images;
 		}
@@ -1365,12 +1369,13 @@ class WP_Press_This {
 	</div>
 
 	<div id="scanbar" class="scan">
 		<form method="GET">
 			<label for="url-scan" class="screen-reader-text"><?php _e( 'Scan site for content' ); ?></label>
-			<input type="url" name="u" id="url-scan" class="scan-url" value="" placeholder="<?php esc_attr_e( 'Enter a URL to scan' ) ?>" />
+			<input type="url" name="u" id="url-scan" class="scan-url" value="<?php echo esc_attr( $site_data['u'] ) ?>" placeholder="<?php esc_attr_e( 'Enter a URL to scan' ) ?>" />
 			<input type="submit" name="url-scan-submit" id="url-scan-submit" class="scan-submit" value="<?php esc_attr_e( 'Scan' ) ?>" />
+			<?php wp_nonce_field( 'scan-site' ); ?>
 		</form>
 	</div>
 
 	<form id="pressthis-form" method="post" action="post.php" autocomplete="off">
 		<input type="hidden" name="post_ID" id="post_ID" value="<?php echo $post_ID; ?>" />
diff --git a/wp-includes/version.php b/wp-includes/version.php
index 7db8d5c43af..859d2a92f00 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-alpha-40183';
+$wp_version = '4.8-alpha-40195';
 
 /**
  * Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.
  *
  * @global int $wp_db_version

Vulnerable code: 				$data = $this->source_data_fetch_fallback( $data['u'], $data );
			'hasData' => ! empty( $data ),
			<input type="url" name="u" id="url-scan" class="scan-url" value="" placeholder="<?php esc_attr_e( 'Enter a URL to scan' ) ?>" />
$wp_version = '4.8-alpha-40183';
Fixed code: 				if ( isset( $_GET['_wpnonce'] ) && wp_verify_nonce( $_GET['_wpnonce'], 'scan-site' ) ) {
					$data = $this->source_data_fetch_fallback( $data['u'], $data );
				} else {
					$data['errors'] = 'missing nonce';
				}
			'hasData' => ! empty( $data ) && ! isset( $data['errors'] ),
			<input type="url" name="u" id="url-scan" class="scan-url" value="<?php echo esc_attr( $site_data['u'] ) ?>" placeholder="<?php esc_attr_e( 'Enter a URL to scan' ) ?>" />
			<?php wp_nonce_field( 'scan-site' ); ?>
$wp_version = '4.8-alpha-40195';