Protecting You Against Wordfence’s Bad Practices: Information Disclosure Vulnerability in WP Maintenance Mode
Wordfence is putting WordPress website at risk by disclosing vulnerabilities in plugins with critical details needed to double check their work missing, in what appears to be an attempt to profit off of these vulnerabilities. We are releasing those details so that others can review the vulnerabilities to try to limit the damage Wordfence’s practice could cause.
Wordfence describes the information disclosure vulnerability in WP Maintenance Mode version 2.0.6 as “allows a remote attacker to download the list of subscribers from WP Maintenance Mode who have asked to be notified when a site returns to full functionality. To exploit this vulnerability, an attacker simply needs to have a registered account on the victim site with no special permissions.”.
First off, most WordPress website don’t allow the public to create accounts, so saying the attacker “simply needs to have a registered account on the victim site” seems to be misleading at best.
When we went to look for the vulnerability we had a pretty good idea of where it should be, as with this type of issue usually there is a function accessible through AJAX that does not contain the proper checks to make only those intended to access it can. In version 2.0.6 of the plugin, in the file /includes/classes/wp-maintenance-mode-admin.php, we found what seemed to be the relevant function being registered for AJAX access:
41 | add_action('wp_ajax_wpmm_subscribers_export', array($this, 'subscribers_export')); |
But the connected function was already checking to make sure that lower level users could not access the function by exiting if the user cannot manage_options, which only Administrator level users normally have access to:
117 118 119 120 121 122 123 124 125 126 | public function subscribers_export() { global $wpdb; try { // check capabilities if (!current_user_can('manage_options')) { throw new Exception(__('You do not have access to this resource.', $this->plugin_slug)); } // get subscribers and export |
At that point we went looking for something else that could do this particular export and came up empty. Looking at the changes made between 2.0.6 and 2.0.7 didn’t show any changes that would match this vulnerability. We then went back and found the code that checks the user’s capability was added in version 2.0.4. You can see that in version 2.0.3, the function’s code starts without any check first:
104 105 106 107 | public function subscribers_export() { global $wpdb; $results = $wpdb->get_results("SELECT email, insert_date FROM {$wpdb->prefix}wpmm_subscribers ORDER BY id_subscriber DESC", ARRAY_A); |
Not only did Wordfence claim the vulnerability was in version 2.0.6, which it wasn’t, but they claimed they notified the developer of the vulnerabilities in the week of June 26 – July 2. Version 2.0.4 was released on June 16, so something is not right here.
Proof of Concept
The following proof of concept will download the subscriber list, when logged in to WordPress.
Make sure to replace “[path to WordPress]” with the location of WordPress.
http://[path to WordPress]/wp-admin/admin-ajax.php?action=wpmm_subscribers_export