CVE-2026-57381

Property Hive <= 2.2.3 - Unauthenticated Stored Cross-Site Scripting

highImproper Neutralization of Input During Web Page Generation ('Cross-site Scripting')
7.2
CVSS Score
7.2
CVSS Score
high
Severity
2.2.4
Patched in
8d
Time to patch

Description

The Property Hive plugin for WordPress is vulnerable to Stored Cross-Site Scripting in versions up to, and including, 2.2.3 due to insufficient input sanitization and output escaping. This makes it possible for unauthenticated attackers to inject arbitrary web scripts in pages that will execute whenever a user accesses an injected page.

CVSS Vector Breakdown

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

Technical Details

Affected versions<=2.2.3
PublishedJuly 7, 2026
Last updatedJuly 14, 2026
Affected pluginpropertyhive

What Changed in the Fix

Changes introduced in v2.2.4

Loading patch diff...

Source Code

WordPress.org SVN
Research Plan
Unverified

# Exploitation Research Plan: CVE-2026-57381 (Property Hive <= 2.2.3) ## 1. Vulnerability Summary The Property Hive plugin for WordPress is vulnerable to **Unauthenticated Stored Cross-Site Scripting (XSS)**. The vulnerability exists in the handling of property enquiry submissions. Unauthenticated …

Show full research plan

Exploitation Research Plan: CVE-2026-57381 (Property Hive <= 2.2.3)

1. Vulnerability Summary

The Property Hive plugin for WordPress is vulnerable to Unauthenticated Stored Cross-Site Scripting (XSS). The vulnerability exists in the handling of property enquiry submissions. Unauthenticated users can submit the property enquiry/book viewing form with malicious JavaScript in fields such as the enquiry message. This input is stored in the database as a "Contact" or "Enquiry" record (custom post type) without sufficient sanitization. When an administrative user views the enquiry in the Property Hive CRM or contact management dashboard, the script executes in their browser context.

2. Attack Vector Analysis

  • Endpoint: wp-admin/admin-ajax.php
  • Action: propertyhive_submit_enquiry (or ph_submit_enquiry)
  • Vulnerable Parameter: enquiry (the message body) or first_name/last_name.
  • Authentication: None (Unauthenticated).
  • Preconditions: A property must exist on the site for the enquiry form to be accessible and for the nonce to be generated.
  • Vector: Stored XSS. The payload is saved to the database (likely as ph_contact or ph_enquiry post type) and executed when an admin views the CRM.

3. Code Flow

  1. Frontend Entry: The user visits a property details page. The template (e.g., includes/salient-widgets/property-enquiry-form.php or templates/enquiry-form.php) renders the enquiry form.
  2. Script Loading: PH_Frontend_Scripts::load_scripts (referenced in includes/class-ph-elementor.php) enqueues the enquiry form JS and localizes the propertyhive_vars object containing the enquiry_nonce.
  3. Submission: The user submits the form via AJAX. The request is sent to admin-ajax.php with the action propertyhive_submit_enquiry.
  4. AJAX Handler: PH_Ajax::submit_enquiry() (in includes/class-ph-ajax.php) receives the request.
  5. Processing: The handler verifies the nonce using check_ajax_referer('propertyhive_submit_enquiry', 'nonce') (inferred).
  6. Sink (Storage): The handler uses wp_insert_post() to create a new record of type ph_contact or ph_enquiry. The enquiry parameter is stored in the post_content or post_meta without rigorous sanitization (missing sanitize_textarea_field or using an ineffective ph_clean).
  7. Trigger (Execution): An admin logs in and navigates to Property Hive -> Contacts or Property Hive -> Enquiries. The dashboard renders the list of submissions. The stored payload is echoed into the page without output escaping (missing esc_html or wp_kses).

4. Nonce Acquisition Strategy

The Property Hive enquiry form requires a nonce for the propertyhive_submit_enquiry action. This nonce is exposed in the frontend for unauthenticated users.

  1. Identify Trigger: The enquiry form appears on property detail pages.
  2. Create Setup: Create a dummy property to ensure the form is active.
  3. Navigation: Use the execution agent to navigate to the property page.
  4. Extraction: Use browser_eval to extract the nonce from the localized JavaScript object propertyhive_vars.

Verification Command:

browser_eval("window.propertyhive_vars?.enquiry_nonce || window.propertyhive_vars?.nonce")

Note: In Property Hive, the variable is typically propertyhive_vars and the key is enquiry_nonce.

5. Exploitation Strategy

Step 1: Discover a Property

Find an existing property or create one using WP-CLI.

Step 2: Extract Nonce

Navigate to the property URL and extract the enquiry_nonce from window.propertyhive_vars.

Step 3: Submit Malicious Enquiry

Send a POST request to admin-ajax.php with the XSS payload.

  • URL: http://<target>/wp-admin/admin-ajax.php
  • Method: POST
  • Content-Type: application/x-www-form-urlencoded
  • Parameters:
    • action: propertyhive_submit_enquiry
    • nonce: [EXTRACTED_NONCE]
    • first_name: Attacker
    • last_name: User
    • email: attacker@example.com
    • enquiry: <img src=x onerror="alert('CVE-2026-57381_XSS_Triggered')">
    • post_id: [PROPERTY_ID]

Step 4: Admin Trigger

The payload will execute when an admin visits the "Contacts" list:
http://<target>/wp-admin/edit.php?post_type=ph_contact

6. Test Data Setup

  1. Create Property:
    wp post create --post_type=property --post_title="Vulnerable Property" --post_status=publish
    
  2. Ensure Plugin Settings: Ensure the enquiry form is enabled (default behavior).
  3. Identify Property URL:
    wp post list --post_type=property --field=ID --title="Vulnerable Property" | xargs -I {} wp post get {} --field=guid
    

7. Expected Results

  • The admin-ajax.php response should indicate success (e.g., {"success":true}).
  • A new post of type ph_contact should exist in the database containing the payload.
  • When the browser navigates to the admin contact list, an alert box with CVE-2026-57381_XSS_Triggered should appear.

8. Verification Steps

  1. Check Database for Payload:
    wp post list --post_type=ph_contact --fields=post_title,post_content
    # OR if stored in meta:
    wp post meta list $(wp post list --post_type=ph_contact --format=ids | awk '{print $1}')
    
  2. Verify Presence of Unsanitized Data:
    Check if the string <img src=x onerror= exists verbatim in the post_content or meta values for the newly created contact.

9. Alternative Approaches

  • Field Variations: If the enquiry field is sanitized, try the first_name or last_name fields, as these are often used to build the post_title and might be rendered unescaped in the admin list.
  • Request Method: If the AJAX action is not found, check the README.txt for "Property enquiry" features and look for alternative actions in includes/class-ph-ajax.php (if available via grep).
  • Bypass ph_clean: If ph_clean is used, it often maps to sanitize_text_field. Test if attribute-based payloads like "><svg onload=alert(1)> bypass it if the value is later echoed into an HTML attribute.

Check if your site is affected.

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