CVE-2026-24986

Simple Membership WP user Import <= 1.9.1 - Cross-Site Request Forgery

mediumCross-Site Request Forgery (CSRF)
4.3
CVSS Score
4.3
CVSS Score
medium
Severity
1.9.2
Patched in
22d
Time to patch

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:N
Attack Vector
Network
Attack Complexity
Low
Privileges Required
None
User Interaction
Required
Scope
Unchanged
None
Confidentiality
Low
Integrity
None
Availability

Technical Details

Affected versions<=1.9.1
PublishedJanuary 20, 2026
Last updatedFebruary 10, 2026
Research Plan
Unverified

# 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_init or 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)

  1. Registration: The plugin registers a submenu page under the "Simple Membership" menu using add_submenu_page.
  2. Hook: A function is hooked to admin_init or defines the callback for the submenu page to handle form submissions.
  3. 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.
  4. 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_tbl table.

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:
    1. Locate the admin page for the plugin: wp-admin/admin.php?page=simple-membership-wp-user-import (inferred slug).
    2. Use browser_navigate to visit this page as an admin.
    3. Use browser_eval to search the DOM for any hidden nonce fields: document.querySelector('input[name="_wpnonce"]')?.value.
    4. Compare the action string in wp_create_nonce (found in the source code) with the action string in check_admin_referer.

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

  1. Install Plugins: Ensure both simple-membership and simple-membership-wp-user-import (<= 1.9.1) are active.
  2. Create WordPress Users: Create 5-10 dummy WordPress users with the "Subscriber" role.
  3. Create Membership Level: In Simple Membership, create at least one membership level (e.g., "Basic" with ID 1).
  4. Admin Login: The agent must have a session for the admin user.

7. Expected Results

  • The http_request should return a 302 redirect or a 200 OK indicating 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:

  1. add_action( 'admin_init', ... )
  2. if (isset($_POST['...']))
  3. check_admin_referer (confirm its absence).
Research Findings
Static analysis — not yet PoC-verified

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

--- simple-membership-wp-user-import/swpm-wp-import.php
+++ simple-membership-wp-user-import/swpm-wp-import.php
@@ -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.