Project: Wordpress Plugin Jetpack by WordPress.com 6.6.1

Vulnerability: #9217822 (2018-10-30 09:27:05)

Warning

There are many false positives, or unexploitable vulnerabilities. Please create working "PoC" exploit before reporting anything to vendor!

Details:

Sink Standard::http_build_query
Risk _POST
/jetpack/class.jetpack.php:5459 (show/hide source)
5439  			$user = new WP_User( $user_id );
5440  			if ( ! $user || ! $user->exists() ) {
5441  				return false;
5442  			}
5443  		}
5444  
5445  		$token = Jetpack_Data::get_access_token( $user_id );
5446  		if ( ! $token ) {
5447  			return false;
5448  		}
5449  
5450  		$token_check = "$token_key.";
5451  		if ( ! hash_equals( substr( $token->secret, 0, strlen( $token_check ) ), $token_check ) ) {
5452  			return false;
5453  		}
5454  
5455  		require_once JETPACK__PLUGIN_DIR . 'class.jetpack-signature.php';
5456  
5457  		$jetpack_signature = new Jetpack_Signature( $token->secret, (int) Jetpack_Options::get_option( 'time_diff' ) );
5458  		if ( isset( $_POST['_jetpack_is_multipart'] ) ) {
5459 $post_data = $_POST;
5460 $file_hashes = array(); 5461 foreach ( $post_data as $post_data_key => $post_data_value ) {
Threat level 1

Callstack:

Jetpack::verify_xml_rpc_signature /jetpack/class.jetpack.php:5476 (show/hide source)
5456  
5457  		$jetpack_signature = new Jetpack_Signature( $token->secret, (int) Jetpack_Options::get_option( 'time_diff' ) );
5458  		if ( isset( $_POST['_jetpack_is_multipart'] ) ) {
5459  			$post_data   = $_POST;
5460  			$file_hashes = array();
5461  			foreach ( $post_data as $post_data_key => $post_data_value ) {
5462  				if ( 0 !== strpos( $post_data_key, '_jetpack_file_hmac_' ) ) {
5463  					continue;
5464  				}
5465  				$post_data_key = substr( $post_data_key, strlen( '_jetpack_file_hmac_' ) );
5466  				$file_hashes[$post_data_key] = $post_data_value;
5467  			}
5468  
5469  			foreach ( $file_hashes as $post_data_key => $post_data_value ) {
5470  				unset( $post_data["_jetpack_file_hmac_{$post_data_key}"] );
5471  				$post_data[$post_data_key] = $post_data_value;
5472  			}
5473  
5474  			ksort( $post_data );
5475  
5476 $body = http_build_query( stripslashes_deep( $post_data ) );
5477 } elseif ( is_null( $this->HTTP_RAW_POST_DATA ) ) { 5478 $body = file_get_contents( 'php://input' );
Jetpack::__construct /jetpack/class.jetpack.php:568 (show/hide source)
548  			$this->xmlrpc_server = new Jetpack_XMLRPC_Server();
549  
550  			$this->require_jetpack_authentication();
551  
552  			if ( Jetpack::is_active() ) {
553  				// Hack to preserve $HTTP_RAW_POST_DATA
554  				add_filter( 'xmlrpc_methods', array( $this, 'xmlrpc_methods' ) );
555  
556  				$signed = $this->verify_xml_rpc_signature();
557  				if ( $signed && ! is_wp_error( $signed ) ) {
558  					// The actual API methods.
559  					add_filter( 'xmlrpc_methods', array( $this->xmlrpc_server, 'xmlrpc_methods' ) );
560  				} else {
561  					// The jetpack.authorize method should be available for unauthenticated users on a site with an
562  					// active Jetpack connection, so that additional users can link their account.
563  					add_filter( 'xmlrpc_methods', array( $this->xmlrpc_server, 'authorize_xmlrpc_methods' ) );
564  				}
565  			} else {
566  				// The bootstrap API methods.
567  				add_filter( 'xmlrpc_methods', array( $this->xmlrpc_server, 'bootstrap_xmlrpc_methods' ) );
568 $signed = $this->verify_xml_rpc_signature();
569 if ( $signed && ! is_wp_error( $signed ) ) { 570 // the jetpack Provision method is available for blog-token-signed requests
Jetpack::init /jetpack/class.jetpack.php:352 (show/hide source)
332  	public $json_api_authorization_request = array();
333  
334  	/**
335  	 * @var string Transient key used to prevent multiple simultaneous plugin upgrades
336  	 */
337  	public static $plugin_upgrade_lock_key = 'jetpack_upgrade_lock';
338  
339  	/**
340  	 * Holds the singleton instance of this class
341  	 * @since 2.3.3
342  	 * @var Jetpack
343  	 */
344  	static $instance = false;
345  
346  	/**
347  	 * Singleton
348  	 * @static
349  	 */
350  	public static function init() {
351  		if ( ! self::$instance ) {
352 self::$instance = new Jetpack;
353 354 self::$instance->plugin_upgrade();
Jetpack::deactivate_module /jetpack/class.jetpack.php:3011 (show/hide source)
2991  		if ( $exit ) {
2992  			exit;
2993  		}
2994  		return true;
2995  	}
2996  
2997  	function activate_module_actions( $module ) {
2998  		_deprecated_function( __METHOD__, 'jetpack-4.2' );
2999  	}
3000  
3001  	public static function deactivate_module( $module ) {
3002  		/**
3003  		 * Fires when a module is deactivated.
3004  		 *
3005  		 * @since 1.9.0
3006  		 *
3007  		 * @param string $module Module slug.
3008  		 */
3009  		do_action( 'jetpack_pre_deactivate_module', $module );
3010  
3011 $jetpack = Jetpack::init();
3012 3013 $active = Jetpack::get_active_modules();
WPCOM_JSON_API_Site_Settings_Endpoint::update_settings /jetpack/json-endpoints/class.wpcom-json-api-site-settings-endpoint.php:570 (show/hide source)
550  							? Jetpack::activate_module( $blog_id, 'search' )
551  							: Jetpack::activate_module( 'search', false, false );
552  					} else {
553  						$jetpack_search_update_success = $is_wpcom
554  							? Jetpack::deactivate_module( $blog_id, 'search' )
555  							: Jetpack::deactivate_module( 'search' );
556  					}
557  					$updated[ $key ] = (bool) $value;
558  					break;
559  				case 'jetpack_relatedposts_enabled':
560  				case 'jetpack_relatedposts_show_thumbnails':
561  				case 'jetpack_relatedposts_show_headline':
562  					if ( ! $this->jetpack_relatedposts_supported() ) {
563  						break;
564  					}
565  					if ( 'jetpack_relatedposts_enabled' === $key && method_exists( 'Jetpack', 'is_module_active' ) && $this->jetpack_relatedposts_supported() ) {
566  						$before_action = Jetpack::is_module_active('related-posts');
567  						if ( $value ) {
568  							Jetpack::activate_module( 'related-posts', false, false );
569  						} else {
570 Jetpack::deactivate_module( 'related-posts' );
571 } 572 $after_action = Jetpack::is_module_active('related-posts');
WPCOM_JSON_API_Site_Settings_Endpoint::callback /jetpack/json-endpoints/class.wpcom-json-api-site-settings-endpoint.php:161 (show/hide source)
141  
142  		if ( ! is_user_logged_in() ) {
143  			return new WP_Error( 'Unauthorized', 'You must be logged-in to manage settings.', 401 );
144  		} else if ( ! current_user_can( 'manage_options' ) ) {
145  			return new WP_Error( 'Forbidden', 'You do not have the capability to manage settings for this site.', 403 );
146  		}
147  
148  		if ( 'GET' === $this->api->method ) {
149  			/**
150  			 * Fires on each GET request to a specific endpoint.
151  			 *
152  			 * @module json-api
153  			 *
154  			 * @since 3.2.0
155  			 *
156  			 * @param string sites.
157  			 */
158  			do_action( 'wpcom_json_api_objects', 'sites' );
159  			return $this->get_settings_response();
160  		} else if ( 'POST' === $this->api->method ) {
161 return $this->update_settings();
162 } else { 163 return new WP_Error( 'bad_request', 'An unsupported request method was used.' );
WPCOM_JSON_API_Site_Settings_V1_2_Endpoint::callback /jetpack/json-endpoints/class.wpcom-json-api-site-settings-v1-2-endpoint.php:130 (show/hide source)
110  	'example_request' => 'https://public-api.wordpress.com/rest/v1/sites/en.blog.wordpress.com/settings?pretty=1',
111  ) );
112  
113  class WPCOM_JSON_API_Site_Settings_V1_2_Endpoint extends WPCOM_JSON_API_Site_Settings_Endpoint {
114  
115  	public static $site_format = array(
116  		'ID'             => '(int) Site ID',
117  		'name'           => '(string) Title of site',
118  		'description'    => '(string) Tagline or description of site',
119  		'URL'            => '(string) Full URL to the site',
120  		'locale'         => '(string) Locale code of the site',
121  		'locale_variant' => '(string) Locale variant code for the site, if set',
122  		'settings'       => '(array) An array of options/settings for the blog. Only viewable by users with post editing rights to the site.',
123  	);
124  
125  
126  	function callback( $path = '', $blog_id = 0 ) {
127  		add_filter( 'site_settings_endpoint_update_locale', array( $this, 'update_locale' ) );
128  		add_filter( 'site_settings_endpoint_get',           array( $this, 'return_locale' ) );
129  		add_filter( 'site_settings_site_format',            array( $this, 'site_format' ) );
130 return parent::callback( $path, $blog_id );
131 } 132
WPCOM_JSON_API_Site_Settings_V1_3_Endpoint::callback /jetpack/json-endpoints/class.wpcom-json-api-site-settings-v1-3-endpoint.php:126 (show/hide source)
106  	'response_format' => array(
107  		'updated' => '(array)'
108  	),
109  
110  	'example_request' => 'https://public-api.wordpress.com/rest/v1/sites/en.blog.wordpress.com/settings?pretty=1',
111  ) );
112  
113  class WPCOM_JSON_API_Site_Settings_V1_3_Endpoint extends WPCOM_JSON_API_Site_Settings_V1_2_Endpoint {
114  	protected function get_defaults() {
115  		return array(
116  			'code'                 => '',
117  			'anonymize_ip'         => false,
118  			'ec_track_purchases'   => false,
119  			'ec_track_add_to_cart' => false
120  		);
121  	}
122  
123  	function callback( $path = '', $blog_id = 0 ) {
124  		add_filter( 'site_settings_endpoint_get', array( $this, 'filter_site_settings_endpoint_get' ) );
125  		add_filter( 'site_settings_update_wga', array( $this, 'filter_update_google_analytics' ), 10, 2 );
126 return parent::callback( $path, $blog_id );
127 } 128