[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$fH9006yonm60iKG6_KjoPzmkhH5-Vl7NlXs4KZHJcEP4":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":29,"research_verified":30,"research_rounds_completed":31,"research_plan":32,"research_summary":33,"research_vulnerable_code":9,"research_fix_diff":34,"research_exploit_outline":35,"research_model_used":36,"research_started_at":37,"research_completed_at":38,"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":30,"poc_model_used":9,"poc_verification_depth":9,"poc_exploit_code_gated":30,"source_links":39},"CVE-2026-3488","wp-statistics-missing-authorization-to-authenticated-subscriber-sensitive-information-exposure-and-privacy-audit-manipul","WP Statistics \u003C= 14.16.4 - Missing Authorization to Authenticated (Subscriber+) Sensitive Information Exposure and Privacy Audit Manipulation","The WP Statistics plugin for WordPress is vulnerable to Missing Authorization in all versions up to, and including, 14.16.4. This is due to missing capability checks on multiple AJAX handlers including `wp_statistics_get_filters`, `wp_statistics_getPrivacyStatus`, `wp_statistics_updatePrivacyStatus`, and `wp_statistics_dismiss_notices`. These endpoints only verify a `wp_rest` nonce via `check_ajax_referer()` but do not enforce any capability checks such as `current_user_can()` or the plugin's own `User::Access()` method. Since the `wp_rest` nonce is available to all authenticated WordPress users, this makes it possible for authenticated attackers, with Subscriber-level access and above, to access sensitive analytics data (user IDs, usernames, emails, visitor tracking data), retrieve and modify privacy audit compliance status, and dismiss administrative notices.","wp-statistics",null,"\u003C=14.16.4","14.16.5","medium",6.5,"CVSS:3.1\u002FAV:N\u002FAC:L\u002FPR:N\u002FUI:N\u002FS:U\u002FC:L\u002FI:L\u002FA:N","Missing Authorization","2026-04-16 13:23:33","2026-04-17 01:24:38",[19],"https:\u002F\u002Fwww.wordfence.com\u002Fthreat-intel\u002Fvulnerabilities\u002Fid\u002Fb1938ba4-ced7-455b-8772-a192d9cb0897?source=api-prod",1,[22,23,24,25,26,27,28],"assets\u002Fdev\u002Fjavascript\u002Fchart.js","assets\u002Fdev\u002Fjavascript\u002Fcomponents\u002Ftraffic-hour-chart.js","assets\u002Fdev\u002Fjavascript\u002Fconfig.js","assets\u002Fdev\u002Fjavascript\u002Fhelper.js","assets\u002Fdev\u002Fjavascript\u002Ftracker.js","assets\u002Fjs\u002Ftinymce.min.js","assets\u002Fjs\u002Ftracker.js","researched",false,3,"# Exploitation Research Plan - CVE-2026-3488\n\n## 1. Vulnerability Summary\nThe **WP Statistics** plugin (\u003C= 14.16.4) contains a missing authorization vulnerability within several AJAX handlers. While these handlers correctly verify a WordPress nonce (specifically the `wp_rest` action nonce), they fail to implement any capability checks (e.g., `current_user_can()` or the plugin's internal `User::Access()` method). \n\nBecause the `wp_rest` nonce is automatically generated and provided to all authenticated users (including low-privileged **Subscribers**) for standard WordPress functionality, an authenticated attacker can invoke these administrative functions to leak sensitive analytics data, modify privacy audit settings, and dismiss administrative notices.\n\n## 2. Attack Vector Analysis\n- **Endpoint:** `\u002Fwp-admin\u002Fadmin-ajax.php`\n- **Method:** POST\n- **Authentication:** Required (Subscriber-level or higher)\n- **Vulnerable Actions:**\n    - `wp_statistics_get_filters` (Data Exposure)\n    - `wp_statistics_getPrivacyStatus` (Info Leak)\n    - `wp_statistics_updatePrivacyStatus` (Unauthorized Modification)\n    - `wp_statistics_dismiss_notices` (Action Unauthorized)\n- **Key Parameter:** `wps_nonce` (containing a valid `wp_rest` nonce).\n\n## 3. Code Flow\n1. **Entry Point:** A request is sent to `admin-ajax.php` with `action=wp_statistics_...`.\n2. **Hook Registration:** The plugin registers AJAX handlers using `add_action('wp_ajax_...', ...)`.\n3. **Nonce Verification:** The handler calls `check_ajax_referer('wp_rest', 'wps_nonce')` (as indicated by the vulnerability description and `assets\u002Fdev\u002Fjavascript\u002Fhelper.js` usage).\n4. **Vulnerable Sink:** The handler proceeds to execute logic (e.g., fetching database records of visitors\u002Fusers or updating options) without calling `current_user_can('manage_options')` or equivalent.\n5. **Data Return:** The sensitive data is returned via `wp_send_json_success()`.\n\n## 4. Nonce Acquisition Strategy\nThe plugin uses the standard WordPress REST API nonce for its AJAX operations. This nonce is globally available to any logged-in user in the WordPress admin dashboard.\n\n1. **Identification:** The JS source `assets\u002Fdev\u002Fjavascript\u002Fhelper.js` shows the plugin expects the nonce in a variable: `wps_js.global.rest_api_nonce`.\n2. **Localization:** This is localized into the page as part of the `wps_global` object (seen in `assets\u002Fdev\u002Fjavascript\u002Fconfig.js`).\n3. **Acquisition Steps:**\n    - Log in as a **Subscriber**.\n    - Navigate to the WordPress Dashboard (`\u002Fwp-admin\u002Findex.php`).\n    - Use `browser_eval` to extract the nonce:\n      ```javascript\n      window.wps_global?.rest_api_nonce || window.wpApiSettings?.nonce\n      ```\n    - Note: In standard WordPress, `window.wpApiSettings.nonce` also contains the `wp_rest` nonce and is often equivalent.\n\n## 5. Exploitation Strategy\n\n### Step 1: Data Exposure (Sensitive Filters\u002FUsers)\n**Action:** `wp_statistics_get_filters`\n- **Goal:** Retrieve a list of filters that may include user IDs, usernames, or site structure.\n- **Request:**\n```http\nPOST \u002Fwp-admin\u002Fadmin-ajax.php HTTP\u002F1.1\nContent-Type: application\u002Fx-www-form-urlencoded\n\naction=wp_statistics_get_filters&wps_nonce=[EXTRACTED_NONCE]\n```\n\n### Step 2: Privacy Audit Manipulation\n**Action:** `wp_statistics_updatePrivacyStatus`\n- **Goal:** Disable or modify privacy features.\n- **Request (Inferred parameters):**\n```http\nPOST \u002Fwp-admin\u002Fadmin-ajax.php HTTP\u002F1.1\nContent-Type: application\u002Fx-www-form-urlencoded\n\naction=wp_statistics_updatePrivacyStatus&wps_nonce=[EXTRACTED_NONCE]&status=0\n```\n*(Note: If `status` is not the correct key, we will attempt to \"get\" first to see the structure).*\n\n### Step 3: Privacy Status Exposure\n**Action:** `wp_statistics_getPrivacyStatus`\n- **Goal:** Read the current compliance and audit status.\n- **Request:**\n```http\nPOST \u002Fwp-admin\u002Fadmin-ajax.php HTTP\u002F1.1\nContent-Type: application\u002Fx-www-form-urlencoded\n\naction=wp_statistics_getPrivacyStatus&wps_nonce=[EXTRACTED_NONCE]\n```\n\n## 6. Test Data Setup\n1. **User Creation:** Create a subscriber user `attacker`.\n2. **Plugin Content:** Ensure the plugin has some data. Generate at least one visit by navigating the site as an anonymous user.\n3. **Settings:** Ensure some privacy settings are configured in the WP Statistics settings page so they can be read\u002Fmodified.\n\n## 7. Expected Results\n- **Success:** The server returns a `200 OK` with a JSON body: `{\"success\":true,\"data\":{...}}`.\n- **Payload Contents:** The `data` object will contain sensitive environment details, such as visitor logs, user lists (IDs\u002FEmails), or the current plugin configuration\u002Fprivacy status.\n- **Unauthorized Status:** The attacker (Subscriber) should have received `403 Forbidden` if a capability check were present, but they instead receive the administrative data.\n\n## 8. Verification Steps\n1. **Check Options via CLI:**\n   ```bash\n   wp option get wp_statistics_privacy_details (or similar option name)\n   ```\n   Verify if values changed after the `updatePrivacyStatus` exploit.\n2. **Inspect Response:** Verify the JSON response of `wp_statistics_get_filters` contains real user data (e.g., IDs from the `wp_users` table).\n\n## 9. Alternative Approaches\nIf the `wp_rest` nonce is not available on the dashboard for Subscribers:\n- **Search for Shortcodes:** Identify any plugin shortcode (e.g., `[wpstatistics...]` seen in `assets\u002Fjs\u002Ftinymce.min.js`) and place it on a post.\n- **Navigate to Post:** Browse to that post as the Subscriber. The plugin's JS and localized `wps_global` object will likely be enqueued there to support frontend stats\u002Fcharts.\n- **Dismiss Notices:** Try `action=wp_statistics_dismiss_notices&wps_nonce=...&notice=all` to see if administrative UI elements disappear for all users.","The WP Statistics plugin for WordPress (\u003C= 14.16.4) fails to implement capability checks in several AJAX handlers, relying solely on a REST API nonce for verification. This allows authenticated users with subscriber-level permissions to access sensitive analytics data, modify privacy settings, and dismiss administrative notifications.","diff -ru \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fwp-statistics\u002F14.16.4\u002Fassets\u002Fdev\u002Fjavascript\u002Fchart.js \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fwp-statistics\u002F14.16.5\u002Fassets\u002Fdev\u002Fjavascript\u002Fchart.js\n--- \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fwp-statistics\u002F14.16.4\u002Fassets\u002Fdev\u002Fjavascript\u002Fchart.js\t2025-12-01 07:17:10.000000000 +0000\n+++ \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fwp-statistics\u002F14.16.5\u002Fassets\u002Fdev\u002Fjavascript\u002Fchart.js\t2026-04-11 07:13:12.000000000 +0000\n@@ -125,7 +125,7 @@\n                 \u003Cdiv class=\"current-data\">\n                     \u003Cdiv>\n                         \u003Cspan class=\"current-data__color\" style=\"background-color: ${dataset.hoverPointBackgroundColor};\">\u003C\u002Fspan>\n-                        ${dataset.label}\n+                        ${wps_js.escapeHtml(dataset.label)}\n                     \u003C\u002Fdiv>\n                     \u003Cspan class=\"current-data__value\">${value.toLocaleString()}\u003C\u002Fspan>\n                 \u003C\u002Fdiv>`;\n@@ -496,7 +496,7 @@\n                 \u003C\u002Fdiv>` : '';\n \n                 legendItem.innerHTML = `\n-                \u003Cspan>${dataset.label}\u003C\u002Fspan>\n+                \u003Cspan>${wps_js.escapeHtml(dataset.label)}\u003C\u002Fspan>\n                 \u003Cdiv>\n                     \u003Cdiv class=\"current-data\">\n                         \u003Cspan class=\"wps-postbox-chart--item--color\" style=\"border-color: ${dataset.borderColor}\">\u003C\u002Fspan>\n... (truncated)","1. Authenticate to the WordPress site as a user with at least Subscriber-level permissions.\n2. Access the dashboard and extract the WordPress REST API nonce (wp_rest action), which the plugin localizes in the `wps_global.rest_api_nonce` or `wpApiSettings.nonce` JavaScript objects.\n3. Construct a POST request to `\u002Fwp-admin\u002Fadmin-ajax.php` with the `wps_nonce` parameter set to the extracted nonce.\n4. Set the `action` parameter to a vulnerable administrative handler, such as `wp_statistics_get_filters` (to retrieve sensitive user and visitor data) or `wp_statistics_updatePrivacyStatus` (to modify the site's privacy configuration).\n5. Observe that the server processes the request and returns administrative information or modifies settings, despite the attacker lacking the necessary capabilities, because the plugin only verifies the nonce and not the user's role.","gemini-3-flash-preview","2026-04-20 20:30:08","2026-04-20 20:30:45",{"type":40,"vulnerable_version":41,"fixed_version":11,"vulnerable_browse":42,"vulnerable_zip":43,"fixed_browse":44,"fixed_zip":45,"all_tags":46},"plugin","14.16.4","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fwp-statistics\u002Ftags\u002F14.16.4","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fwp-statistics.14.16.4.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fwp-statistics\u002Ftags\u002F14.16.5","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fwp-statistics.14.16.5.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fwp-statistics\u002Ftags"]