Motors – Car Dealership & Classified Listings Plugin < 1.4.107 - Missing Authorization
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:NTechnical Details
<1.4.107What Changed in the Fix
Changes introduced in v1.4.107
Source Code
WordPress.org SVNThis 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 potentiallylisting_manager_get_form) - Authentication: Required (Subscriber level or above).
- Payload Parameters:
action:listing_manager_save_formnonce: 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:featuresoroption.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
- Entry Point: The AJAX action
listing_manager_save_formis triggered via POST. - JS Source:
assets/js/listing-manager/listing-manager-features.js(lines 104-129) andassets/js/listing-manager/listing-manager-options.js. - Vulnerable Sink (PHP): The PHP handler for
listing_manager_save_form(likely in anincludes/directory not fully provided, but referenced by JS) fails to verify that thecurrent_user_can('manage_options')or that the current user is thepost_authorof thelisting_id. - Execution: The handler processes the
term_nameordataand useswp_set_object_terms()orupdate_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.
- Identify Page: The Listing Manager is active on the "Add Car" or "Edit Car" pages of the dealership dashboard.
- Create Setup: Ensure the plugin is configured to allow users to add listings.
- 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_evalto inspect the global scope. The variables are likely part of a localized object. - Verified JS Identifiers:
- Object likely:
window.listingManagerorwindow.mvl_listing_manager_vars. - Key:
nonceornonce_get_form.
- Object likely:
- 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.
- Step 1: Setup Content: Create a car listing as an Administrator. Note its
listing_id. - Step 2: Obtain Nonce: Navigate to the dealership dashboard as a Subscriber and extract the
noncevariable. - 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
- Send a POST request to
- 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
- Administrator: Default admin.
- Car Listing: Use WP-CLI to create a listing.
(Note: post_type might bewp post create --post_type=listings --post_title="Admin Car" --post_status=publish --post_author=1stm-listingsorlistingsdepending on plugin config; check withwp post-type list). - Subscriber:
wp user create attacker attacker@example.com --role=subscriber --user_pass=password - 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
- Check Metadata/Terms via WP-CLI:
# List terms for the Admin's car ID wp post term list [ADMIN_LISTING_ID] stm_features - 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 inassets/js/frontend/init.js). - Payload: Attempt to send a
user_idparameter 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--
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
@@ -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.