Import and export users and customers <= 1.29.7 - Privilege Escalation to Administrator via save_extra_user_profile_fields
Description
The Import and export users and customers plugin for WordPress is vulnerable to privilege escalation in all versions up to, and including, 1.29.7. This is due to the 'save_extra_user_profile_fields' function not properly restricting which user meta keys can be updated via profile fields. The 'get_restricted_fields' method does not include sensitive meta keys such as 'wp_capabilities'. This makes it possible for unauthenticated attackers to escalate their privileges to Administrator by submitting a crafted registration request that sets the 'wp_capabilities' meta key. The vulnerability can only be exploited if the "Show fields in profile" setting is enabled and a CSV with a wp_capabilities column header has been previously imported.
CVSS Vector Breakdown
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:HTechnical Details
<=1.29.7What Changed in the Fix
Changes introduced in v2.0
Source Code
WordPress.org SVNThis research plan outlines the steps required to demonstrate an unauthenticated privilege escalation to Administrator in the "Import and export users and customers" plugin. ### 1. Vulnerability Summary The "Import and export users and customers" plugin (versions <= 1.29.7) contains a privilege esc…
Show full research plan
This research plan outlines the steps required to demonstrate an unauthenticated privilege escalation to Administrator in the "Import and export users and customers" plugin.
1. Vulnerability Summary
The "Import and export users and customers" plugin (versions <= 1.29.7) contains a privilege escalation vulnerability. The plugin identifies "extra" user meta fields by tracking column headers from previously imported CSV files. When the "Show fields in profile" setting is enabled, the plugin's save_extra_user_profile_fields function (hooked to user_register and profile_update) iterates through all $_POST data. It updates user meta for any key that matches a "discovered" extra field, provided the key is not in a restricted list.
The vulnerability exists because get_restricted_fields (which uses the acui_restricted_fields filter) fails to include the sensitive wp_capabilities meta key. If an administrator has previously imported a CSV containing a wp_capabilities column, an unauthenticated attacker can provide that key during registration to grant themselves the Administrator role.
2. Attack Vector Analysis
- Endpoint:
wp-login.php?action=register(Standard WordPress registration). - HTTP Method: POST
- Parameters:
user_login: The desired username.user_email: The desired email.wp_capabilities[administrator]: Set to1to grant the administrator role.
- Authentication: None (Unauthenticated).
- Preconditions:
- WordPress must have registration enabled (
users_can_register). - The plugin setting "Show fields in profile" (or "Show fields in registration form") must be enabled.
- An administrator must have previously imported a CSV with a column header named
wp_capabilities. This "registers" the field in the plugin's allowed list.
- WordPress must have registration enabled (
3. Code Flow
- Entry Point:
wp-login.php?action=registercallsregister_new_user(). - User Creation:
register_new_user()callswp_insert_user(). - Hook Trigger:
wp_insert_user()triggers theuser_registeraction hook. - Vulnerable Sink: The plugin's
save_extra_user_profile_fields($user_id)function is executed via theuser_registerhook. - Field Discovery: The function retrieves a list of allowed extra fields (those discovered during previous CSV imports).
- Bypassed Restriction: The function calls
get_restricted_fields()to filter the$_POSTkeys. Sincewp_capabilitiesis not in the returned array of restricted fields, it remains in the processing queue. - Meta Update: The function calls
update_user_meta( $user_id, 'wp_capabilities', $_POST['wp_capabilities'] ). - Role Escalation: WordPress processes the array
['administrator' => '1']and serializes it, effectively granting the new user the Administrator role.
4. Nonce Acquisition Strategy
The exploitation of the user_register hook through the standard WordPress registration form does not require a WordPress nonce for the user_register action itself.
However, if the plugin's settings page requires a nonce for configuration (which the agent will need for setup), the agent should:
- Navigate to the plugin settings page.
- Use
browser_evalto extract any nonce if needed for administrative actions, or usewp-clito modify options directly to simplify the PoC setup.
5. Exploitation Strategy
Step 1: Environment Setup (via WP-CLI)
Enable registration and the required plugin setting.
# Enable user registration
wp option update users_can_register 1
wp option update default_role subscriber
# Enable the specific plugin setting (Grounded in plugin option structure)
# The plugin stores settings in 'acui_settings'
wp eval '
$settings = get_option("acui_settings", []);
$settings["show_fields_in_profile"] = "yes";
update_option("acui_settings", $settings);
'
Step 2: Seed the Vulnerability (Precondition)
Import a CSV with the `wp
Summary
The plugin allows unauthenticated privilege escalation to Administrator by improperly handling user meta updates during registration. When the 'Show fields in profile' setting is enabled and a CSV with a 'wp_capabilities' column has been previously imported, the plugin's `save_extra_user_profile_fields` function will update a new user's capabilities based on registration POST data because 'wp_capabilities' is not included in the restricted fields list.
Vulnerable Code
// The vulnerable logic exists in the main plugin file's save_extra_user_profile_fields function. // It uses get_restricted_fields() which fails to include 'wp_capabilities'. /* Inferred logic based on research plan and vulnerability description: File: import-users-from-csv-with-meta.php (not provided in source, but core to the vulnerability) */ function save_extra_user_profile_fields($user_id) { // ... $extra_fields = get_option('acui_extra_fields', []); $restricted_fields = $this->get_restricted_fields(); // wp_capabilities is missing from this list foreach ($_POST as $key => $value) { if (in_array($key, $extra_fields) && !in_array($key, $restricted_fields)) { update_user_meta($user_id, $key, $value); } } }
Security Fix
@@ -11,7 +11,7 @@ add_filter( 'acui_restricted_fields', array( $this, 'restricted_fields' ), 10, 1 ); add_filter( 'acui_not_meta_fields', array( $this, 'restricted_fields' ), 10, 1 ); add_action( 'acui_documentation_after_plugins_activated', array( $this, 'documentation' ) ); - add_action( 'post_acui_import_single_user', array( $this, 'import' ), 10, 3 ); + add_action( 'acui_post_import_single_user', array( $this, 'import' ), 10, 3 ); add_filter( 'acui_export_columns', array( $this, 'export_columns' ), 10, 1 ); add_filter( 'acui_export_data', array( $this, 'export_data' ), 10, 2 ); } @@ -31,8 +31,8 @@ add_action( 'acui_documentation_after_plugins_activated', array( $this, 'documentation' ) ); add_filter( 'acui_export_columns', array( $this, 'export_columns' ), 10, 1 ); add_filter( 'acui_export_data', array( $this, 'export_data' ), 10, 3 ); - add_action( 'post_acui_import_single_user', array( $this, 'import' ), 10, 10 ); - add_action( 'post_acui_import_single_user', array( $this, 'import_avatar' ), 10, 3 ); + add_action( 'acui_post_import_single_user', array( $this, 'import' ), 10, 10 ); + add_action( 'acui_post_import_single_user', array( $this, 'import_avatar' ), 10, 3 ); }
Exploit Outline
The exploit requires certain preconditions: WordPress must allow user registration, the plugin setting 'Show fields in profile' (or registration form) must be enabled, and an administrator must have previously imported a CSV file containing a column named 'wp_capabilities' (which registers it as a known extra field). An unauthenticated attacker can then perform the following steps: 1. Navigate to the WordPress registration page (wp-login.php?action=register). 2. Submit a registration POST request containing standard fields (user_login, user_email). 3. Include a crafted parameter `wp_capabilities[administrator]=1` in the POST request. 4. Upon registration, the plugin triggers its `save_extra_user_profile_fields` function, which iterates through POST data, finds the 'wp_capabilities' key, and updates the new user's meta data because it is not restricted, effectively granting the new user the Administrator role.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.