WordPress Mesmerize and Materialis themes fixed an authenticated options change vulnerability.

The WordPress Mesmerize theme version 1.6.89 and below (60,000+ active installations) and Materialis theme version 1.0.172 and below (10,000+ active installations) fixed a vulnerability that could allow an authenticated user to modify WordPress core options in the database.

Reference

A CVE ID has been requested and we’ll update this post when it is assigned.

Authenticated Options Change

Note: Because both themes are prone to the same vulnerability, we’ll only see the Mesmerize theme in this advisory.

After installing the theme, it shows a dismissible banner inviting the admin to install its companion plugin:

Clicking on its dismiss (x) button will send an AJAX request to save the banner’s new status to the database wp_options table.
In the __construct method of the “inc/companion.php” script, the admin_notices hook is used to load the banner via the plugin_notice function.

add_action( 'admin_notices', array( __CLASS__, 'plugin_notice' ) );
...
...
public static function plugin_notice() {
   ?>
       <div class="notice notice-success is-dismissible mesmerize-start-with-front-page-notice">
           <div class="notice-content-wrapper">
         <?php mesmerize_require( "/customizer/start-with-frontpage.php" ); ?>
           </div>
       </div>
   <?php
}

The function will also load “/customizer/start-with-frontpage.php” in order to insert the AJAX JS code in the HTML page and a security nonce:

In the same script, the companion_disable_popup action is registered to load the companion_disable_popup function used to handle the AJAX request.

add_action( 'wp_ajax_companion_disable_popup', array( __CLASS__, 'companion_disable_popup' ) );
...
...
public static function companion_disable_popup() {
   $nonce = isset( $_POST['companion_disable_popup_wpnonce'] ) ? $_POST['companion_disable_popup_wpnonce'] : '';

   if ( ! wp_verify_nonce( $nonce, "companion_disable_popup" ) ) {
      die( "wrong nonce" );
   }

   $value  = intval( isset( $_POST['value'] ) ? $_POST['value'] : 0 );
   $option = sanitize_text_field( isset( $_POST['option'] ) ? $_POST['option'] : "mesmerize_companion_disable_popup" );

   update_option( $option, $value );
}

The problem is that the banner is displayed to any logged-in users, as well as its security nonce in the HTML source of every page. Because the companion_disable_popup function only checks the nonce and will pass two user input, $_POST['value'] and $_POST['option'], to the WordPress update_option function, an authenticated user such as a subscriber can copy the nonce and use it to send an AJAX request in order to modify WordPress core options in the wp_options table. The value of $_POST['value'] must be an integer or numerical string and thus can be used by an attacker to enable user registration or comments, to disable all plugins, crash the blog etc.

Timeline

The vulnerability was reported to the wordpress.org team on November 23, 2019 and two new versions 1.6.90 (Mesmerize) and 1.0.173 (Materialis) were released on November 25, 2019.

Recommendations

Update as soon as possible if you have the above themes installed.
If you are using our web application firewall for WordPress, NinjaFirewall WP Edition (free) and NinjaFirewall WP+ Edition (premium), you are protected against this vulnerability.

Stay informed about the latest vulnerabilities in WordPress plugins and themes: @nintechnet