CVE-2026-1934

Motors – Car Dealership & Classified Listings Plugin <= 1.4.103 - Missing Authorization to Authenticated (Subscriber+) Payment Bypass via 'stm_payment_status' Parameter

mediumMissing Authorization
4.3
CVSS Score
4.3
CVSS Score
medium
Severity
1.4.104
Patched in
1d
Time to patch

Description

The Motors – Car Dealership & Classified Listings plugin for WordPress is vulnerable to Payment Bypass via insecure user meta update in all versions up to, and including, 1.4.103 This is due to the stm_save_user_extra_fields() function updating sensitive user meta fields from POST data without verifying that the current user should have permission to modify those fields. The function hooks into the 'personal_options_update' action and only checks current_user_can('edit_user', $user_id), which passes for any user editing their own profile. This makes it possible for authenticated attackers, with Subscriber-level access and above, to set their stm_payment_status to 'completed', bypassing the PayPal payment verification and gaining access to paid Dealer membership features without completing any transaction.

CVSS Vector Breakdown

CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:L/A:N
Attack Vector
Network
Attack Complexity
Low
Privileges Required
Low
User Interaction
None
Scope
Unchanged
None
Confidentiality
Low
Integrity
None
Availability

Technical Details

Affected versions<=1.4.103
PublishedMay 11, 2026
Last updatedMay 12, 2026

What Changed in the Fix

Changes introduced in v1.4.104

Loading patch diff...

Source Code

WordPress.org SVN
Research Plan
Unverified

# Exploitation Research Plan: CVE-2026-1934 ## 1. Vulnerability Summary The **Motors – Car Dealership & Classified Listings** plugin (up to version 1.4.103) contains a missing authorization vulnerability in the `stm_save_user_extra_fields()` function (inferred). This function is responsible for sav…

Show full research plan

Exploitation Research Plan: CVE-2026-1934

1. Vulnerability Summary

The Motors – Car Dealership & Classified Listings plugin (up to version 1.4.103) contains a missing authorization vulnerability in the stm_save_user_extra_fields() function (inferred). This function is responsible for saving additional user profile fields to the database. It is hooked into the standard WordPress profile update actions: personal_options_update and edit_user_profile_update.

The vulnerability exists because the function incorrectly relies on current_user_can('edit_user', $user_id) to authorize updates. In WordPress, every user (including those with the 'Subscriber' role) possesses the edit_user capability for their own $user_id. Consequently, a low-privileged authenticated user can inject sensitive meta keys—specifically stm_payment_status—into the POST request during a profile update. By setting this value to completed, the attacker can bypass payment verification for "Dealer" membership features.

2. Attack Vector Analysis

  • Endpoint: /wp-admin/profile.php
  • Hook: personal_options_update and/or edit_user_profile_update
  • Vulnerable Function: stm_save_user_extra_fields() (inferred from description)
  • HTTP Method: POST
  • Vulnerable Parameter: stm_payment_status
  • Authentication Level: Authenticated (Subscriber+)
  • Preconditions: The attacker must be logged in as a standard user.

3. Code Flow

  1. Entry Point: An authenticated user submits the profile update form at wp-admin/profile.php.
  2. Hook Trigger: WordPress core triggers the personal_options_update action hook during the profile save process.
  3. Vulnerable Callback: The plugin's stm_save_user_extra_fields($user_id) function executes.
  4. Authorization Bypass: The function checks if ( ! current_user_can( 'edit_user', $user_id ) ) return;. Since the user is editing their own profile, this check passes.
  5. Data Sink: The function iterates through or directly accesses $_POST data. It likely calls update_user_meta( $user_id, 'stm_payment_status', $_POST['stm_payment_status'] ) without verifying if the user has permission to modify that specific sensitive field.

4. Nonce Acquisition Strategy

This exploit targets the standard WordPress profile update mechanism. The required nonce is the core WordPress profile nonce, not a plugin-specific one.

  1. Navigate: Use browser_navigate to go to http://localhost:8080/wp-admin/profile.php.
  2. Extract Nonce: The nonce is stored in a hidden input field with the ID _wpnonce.
  3. Extraction Command:
    browser_eval('document.querySelector("#_wpnonce").value')
    
  4. Action Name: The associated action for this nonce is update-user_{$user_id} (handled internally by WordPress).

5. Exploitation Strategy

The goal is to perform a POST request to the profile update handler while including the unauthorized stm_payment_status parameter.

Step-by-Step Plan:

  1. Log in: Authenticate as a Subscriber user.
  2. Identify User ID: Retrieve the current user's ID from the profile page URL or using wp user list --field=ID --login=attacker.
  3. Fetch Nonce: Navigate to /wp-admin/profile.php and extract the _wpnonce.
  4. Formulate Request:
    • URL: http://localhost:8080/wp-admin/profile.php
    • Method: POST
    • Content-Type: application/x-www-form-urlencoded
    • Body Parameters:
      • _wpnonce: [EXTRACTED_NONCE]
      • _wp_http_referer: /wp-admin/profile.php
      • from: profile
      • checkuser_id: [USER_ID]
      • action: update
      • user_id: [USER_ID]
      • nickname: attacker
      • email: attacker@example.com
      • stm_payment_status: completed <-- The Payload

Payload Details:

  • Setting stm_payment_status to completed tells the plugin that the user has successfully paid for their membership, unlocking restricted features.

6. Test Data Setup

  1. Plugin Installation: Ensure "Motors – Car Dealership & Classified Listings" version 1.4.103 is installed and active.
  2. Create Attacker User:
    wp user create attacker attacker@example.com --role=subscriber --user_pass=password123
    
  3. Verify Initial State:
    wp user meta get $(wp user get attacker --field=ID) stm_payment_status
    
    Expected: Error or empty value.

7. Expected Results

  • Response: The server should return a 302 Redirect back to profile.php?updated=1.
  • Database Change: The user meta table for the attacker's ID should now contain a row with meta_key = 'stm_payment_status' and meta_value = 'completed'.

8. Verification Steps

  1. Check User Meta via CLI:
    wp user meta get $(wp user get attacker --field=ID) stm_payment_status
    
  2. Success Criteria: The command returns completed.

9. Alternative Approaches

If the plugin uses a different field name or requires additional metadata to activate "Dealer" features, the following parameters might also be vulnerable to the same missing authorization:

  • stm_membership_plan_id (inferred)
  • stm_dealer_status (inferred)

If the personal_options_update hook isn't the primary sink, investigate if the plugin provides a frontend profile editor. In many "Motors" versions, there is a frontend dashboard.

  • Frontend Dashboard Endpoint: /account/ or /dealer-dashboard/ (slugs vary).
  • Frontend AJAX Action: Check for wp_ajax_stm_custom_register or wp_ajax_stm_ajax_update_user.
  • Parameter Check: Grep for update_user_meta in the plugin directory to see if other functions are saving stm_payment_status.
grep -r "update_user_meta" . | grep "stm_payment_status"
Research Findings
Static analysis — not yet PoC-verified

Summary

The Motors – Car Dealership & Classified Listings plugin for WordPress is vulnerable to an authorization bypass in versions up to 1.4.103. The stm_save_user_extra_fields() function improperly allows users to update sensitive meta fields, such as stm_payment_status, because it only checks if the user can edit their own profile. An authenticated attacker with Subscriber-level access can set their payment status to 'completed' and bypass PayPal verification to access paid Dealer membership features.

Security Fix

Only in /home/deploy/wp-safety.org/data/plugin-versions/motors-car-dealership-classified-listings/1.4.104/assets/addons/img: forms-editor.png
Only in /home/deploy/wp-safety.org/data/plugin-versions/motors-car-dealership-classified-listings/1.4.104/assets/addons/img: FormsEditor.png
diff -ru /home/deploy/wp-safety.org/data/plugin-versions/motors-car-dealership-classified-listings/1.4.103/assets/css/admin.css /home/deploy/wp-safety.org/data/plugin-versions/motors-car-dealership-classified-listings/1.4.104/assets/css/admin.css
--- /home/deploy/wp-safety.org/data/plugin-versions/motors-car-dealership-classified-listings/1.4.103/assets/css/admin.css	2025-01-07 11:20:12.000000000 +0000
+++ /home/deploy/wp-safety.org/data/plugin-versions/motors-car-dealership-classified-listings/1.4.104/assets/css/admin.css	2026-02-24 03:03:46.000000000 +0000
@@ -493,6 +493,25 @@
     vertical-align: bottom
 }
 
+.mvl-menu-badge {
+    display: inline-block;
+    margin-left: 4px;
+    padding: 1px 5px;
+    font-size: 10px;
+    line-height: 1.2;
+    font-weight: 600;
+    text-transform: uppercase;
+    letter-spacing: .02em;
+    color: #fff;
+    border-radius: 3px;
+    vertical-align: middle
+}
+
+li#toplevel_page_mvl_plugin_settings .wp-submenu .mvl-menu-badge {
+    font-size: 9px;
+    padding: 3px
+}
+
 .wp-admin #stm-payout_edit .stm-order table thead tr, .wp-admin #stm_order_info .stm-order table thead tr {
     background-color: #385bcd
 }
... (truncated)

Exploit Outline

1. Log in to the target WordPress site as a Subscriber-level user. 2. Navigate to the user profile update page at /wp-admin/profile.php. 3. Extract the WordPress profile update nonce (_wpnonce) and the current user's ID from the HTML source. 4. Construct a POST request to /wp-admin/profile.php with the following parameters: action=update, user_id=[CURRENT_USER_ID], and the malicious parameter stm_payment_status=completed. 5. Send the request. The plugin's stm_save_user_extra_fields() function, hooked to personal_options_update, will process the POST data. 6. Because the function checks current_user_can('edit_user', $user_id), and standard WordPress allows users to edit their own profile, the authorization check passes despite the sensitivity of the payment field. 7. The user meta 'stm_payment_status' is updated to 'completed' in the database, granting the attacker access to restricted Dealer membership features without a valid transaction.

Check if your site is affected.

Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.