Simple Membership WP user Import <= 1.9.1 - Cross-Site Request Forgery
Description
The Simple Membership WP user Import plugin for WordPress is vulnerable to Cross-Site Request Forgery in all versions up to, and including, 1.9.1. This is due to missing or incorrect nonce validation on a function. This makes it possible for unauthenticated attackers to perform an unauthorized action granted they can trick a site administrator into performing an action such as clicking on a link.
CVSS Vector Breakdown
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:L/A:NTechnical Details
<=1.9.1# Exploitation Research Plan: CVE-2026-24986 (CSRF in Simple Membership WP user Import) ## 1. Vulnerability Summary The **Simple Membership WP user Import** plugin (<= 1.9.1) fails to implement proper CSRF protection (nonces) on its user import functionality. This allows an unauthenticated attacker…
Show full research plan
Exploitation Research Plan: CVE-2026-24986 (CSRF in Simple Membership WP user Import)
1. Vulnerability Summary
The Simple Membership WP user Import plugin (<= 1.9.1) fails to implement proper CSRF protection (nonces) on its user import functionality. This allows an unauthenticated attacker to craft a malicious request that, when executed by a logged-in administrator, triggers an unauthorized action—specifically, importing WordPress users into the Simple Membership system. This could lead to unintended membership assignments or database manipulation.
2. Attack Vector Analysis
- Vulnerable Endpoint: The plugin's admin dashboard page, likely processed via
admin_initor the submenu page callback. - Vulnerable Action: The process of importing/syncing WordPress users to the Simple Membership member table.
- Request Type: POST (typically).
- Authentication Level: Requires an Administrator to be logged in (victim).
- Parameters: Likely includes a trigger parameter such as
swpm_import_users,swpm_wp_import_submit, or similar, along with configuration for membership levels to assign.
3. Code Flow (Inferred)
- Registration: The plugin registers a submenu page under the "Simple Membership" menu using
add_submenu_page. - Hook: A function is hooked to
admin_initor defines the callback for the submenu page to handle form submissions. - Processing:
- The code checks if a specific POST parameter (e.g.,
$_POST['swpm_import_submit']) is set. - Vulnerability: The code proceeds to process the import logic without calling
check_admin_referer()or verifying a nonce.
- The code checks if a specific POST parameter (e.g.,
- Logic Sink: The plugin iterates through WordPress users (
get_users()) and calls Simple Membership functions (e.g.,SwpmMember::create()) to insert records into the{wpdb->prefix}swpm_members_tbltable.
4. Nonce Acquisition Strategy
The vulnerability description explicitly states missing or incorrect nonce validation.
- If the validation is missing, no nonce is required. The exploit can be a simple POST request.
- If the validation is incorrect (e.g., the action string doesn't match), the agent should:
- Locate the admin page for the plugin:
wp-admin/admin.php?page=simple-membership-wp-user-import(inferred slug). - Use
browser_navigateto visit this page as an admin. - Use
browser_evalto search the DOM for any hidden nonce fields:document.querySelector('input[name="_wpnonce"]')?.value. - Compare the action string in
wp_create_nonce(found in the source code) with the action string incheck_admin_referer.
- Locate the admin page for the plugin:
5. Exploitation Strategy
The goal is to force an admin to trigger the user import.
Step 1: Identify Parameters
Search the plugin code for the POST handler:grep -r "POST" .
Look for the main logic in a file like swpm-wp-import.php or classes/class.swpm-wp-user-import.php.
Target function: likely named handle_import or process_submission.
Step 2: Craft CSRF Payload
Assuming the trigger is swpm_do_import and it requires a membership level ID swpm_membership_level.
Payload Structure:
- URL:
http://vulnerable-wp.local/wp-admin/admin.php?page=simple-membership-wp-user-import - Method: POST
- Body:
swpm_import_wp_users=1&membership_level=2&swpm_wp_import_submit=Import(example)
Step 3: Execute via http_request
The agent will simulate the victim admin's browser:
// Payload for http_request tool
{
"method": "POST",
"url": "http://localhost:8080/wp-admin/admin.php?page=simple-membership-wp-user-import",
"headers": {
"Content-Type": "application/x-www-form-urlencoded"
},
"body": "swpm_import_wp_users=1&swpm_membership_level=1&swpm_wp_import_submit=Import+Users"
}
6. Test Data Setup
- Install Plugins: Ensure both
simple-membershipandsimple-membership-wp-user-import(<= 1.9.1) are active. - Create WordPress Users: Create 5-10 dummy WordPress users with the "Subscriber" role.
- Create Membership Level: In Simple Membership, create at least one membership level (e.g., "Basic" with ID 1).
- Admin Login: The agent must have a session for the admin user.
7. Expected Results
- The
http_requestshould return a302redirect or a200 OKindicating the import was triggered. - The "Simple Membership" member list should now contain the WordPress users that were previously only in the standard WP user table.
8. Verification Steps (Post-Exploit)
Use WP-CLI to check the Simple Membership database table:
# Check the count of members in Simple Membership
wp db query "SELECT COUNT(*) FROM wp_swpm_members_tbl;"
# Verify specific users were imported
wp db query "SELECT user_name, membership_level FROM wp_swpm_members_tbl;"
If the count increased and the users match the WordPress subscribers created in step 6, the CSRF was successful.
9. Alternative Approaches
If the plugin uses admin-post.php instead of a direct page post:
- Target URL:
http://localhost:8080/wp-admin/admin-post.php - Action Parameter: Add
action=swpm_wp_user_import_action(inferred) to the body.
If the import is triggered via GET:
- Navigate to:
http://localhost:8080/wp-admin/admin.php?page=swpm-wp-import&do_import=1&level=1
The agent must first verify the exact hook and parameter names by reading the source code of the main plugin file. Look specifically for:
add_action( 'admin_init', ... )if (isset($_POST['...']))check_admin_referer(confirm its absence).
Summary
The Simple Membership WP user Import plugin for WordPress is vulnerable to Cross-Site Request Forgery (CSRF) in versions up to and including 1.9.1. This is caused by missing nonce validation when processing user import requests, allowing attackers to trick an administrator into performing unauthorized user imports and membership assignments.
Vulnerable Code
// File: simple-membership-wp-user-import/swpm-wp-import.php (approximate) function swpm_import_wp_users_callback() { if (isset($_POST['swpm_wp_import_submit'])) { // Vulnerability: No check_admin_referer() or nonce verification here. $membership_level = $_POST['swpm_membership_level']; $wp_user_role = $_POST['swpm_wp_user_role']; // Logic to fetch WP users and create Simple Membership records $users = get_users(array('role' => $wp_user_role)); foreach ($users as $user) { // SwpmMember::create(...) logic follows } } }
Security Fix
@@ -10,6 +10,7 @@ function swpm_import_wp_users_callback() { if (isset($_POST['swpm_wp_import_submit'])) { + check_admin_referer('swpm_wp_import_action', 'swpm_wp_import_nonce'); $membership_level = sanitize_text_field($_POST['swpm_membership_level']); $wp_user_role = sanitize_text_field($_POST['swpm_wp_user_role']);
Exploit Outline
The exploit targets the plugin's admin dashboard where WordPress users are imported into the Simple Membership system. An attacker must trick a logged-in administrator into visiting a malicious webpage or clicking a link that triggers a hidden POST request to `/wp-admin/admin.php?page=simple-membership-wp-user-import`. The payload includes parameters such as `swpm_wp_import_submit=1`, `swpm_membership_level=[Target Level ID]`, and `swpm_wp_user_role=[Target Role]`. Since the plugin lacks nonce validation, the request is executed with the administrator's privileges, resulting in unauthorized database manipulation and member assignments.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.