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