CVE-2026-0742

Smart Appointment & Booking <= 1.0.7 - Authenticated (Subscriber+) Stored Cross-Site Scripting via saab_save_form_data AJAX Action

mediumImproper Neutralization of Input During Web Page Generation ('Cross-site Scripting')
6.4
CVSS Score
6.4
CVSS Score
medium
Severity
1.0.8
Patched in
1d
Time to patch

Description

The Smart Appointment & Booking plugin for WordPress is vulnerable to Stored Cross-Site Scripting via the saab_save_form_data AJAX action in all versions up to, and including, 1.0.7 due to insufficient input sanitization and output escaping on user supplied attributes. This makes it possible for authenticated attackers, with Subscriber-level access and above, 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:L/UI:N/S:C/C:L/I:L/A:N
Attack Vector
Network
Attack Complexity
Low
Privileges Required
Low
User Interaction
None
Scope
Changed
Low
Confidentiality
Low
Integrity
None
Availability

Technical Details

Affected versions<=1.0.7
PublishedFebruary 3, 2026
Last updatedFebruary 4, 2026

Source Code

WordPress.org SVN
Research Plan
Unverified

# Exploitation Research Plan: CVE-2026-0742 (Smart Appointment & Booking) ## 1. Vulnerability Summary The **Smart Appointment & Booking** plugin (<= 1.0.7) contains a stored cross-site scripting (XSS) vulnerability within its AJAX handling logic. Specifically, the `saab_save_form_data` action fails…

Show full research plan

Exploitation Research Plan: CVE-2026-0742 (Smart Appointment & Booking)

1. Vulnerability Summary

The Smart Appointment & Booking plugin (<= 1.0.7) contains a stored cross-site scripting (XSS) vulnerability within its AJAX handling logic. Specifically, the saab_save_form_data action fails to properly sanitize user-supplied attributes before saving them to the database and fails to escape them upon output. This allows an authenticated user with at least Subscriber privileges to inject malicious scripts that execute when a user (including administrators) views the affected form or its configuration.

2. Attack Vector Analysis

  • Endpoint: /wp-admin/admin-ajax.php
  • AJAX Action: saab_save_form_data (registered via wp_ajax_saab_save_form_data)
  • Vulnerable Parameter: Likely a parameter containing form structure or field attributes (e.g., form_data, fields, or attributes).
  • Authentication: Required (Subscriber or higher).
  • Preconditions: The plugin must be active. A nonce is likely required as part of standard WordPress AJAX patterns.

3. Code Flow (Inferred)

  1. Entry Point: The plugin registers the AJAX handler in its main initialization:
    add_action('wp_ajax_saab_save_form_data', 'saab_save_form_data_handler');
  2. Data Handling: The handler (likely in a file like includes/class-ajax.php or admin/admin-ajax.php) retrieves data from $_POST.
  3. Sink (Storage): The handler saves this data using update_option() or update_post_meta() without calling sanitize_text_field() or wp_kses() on the attributes.
  4. Source (Output): When a booking form is rendered (via shortcode or in the admin dashboard), the saved data is retrieved and echoed directly into the HTML without using esc_attr() or esc_html().

4. Nonce Acquisition Strategy

To bypass the check_ajax_referer or wp_verify_nonce check usually present in AJAX handlers, we must extract the nonce from the WordPress frontend or admin area.

  1. Identify Script Localization: Search the plugin for wp_localize_script. Look for the variable name and the key used for the nonce.
    • Hypothesis: The variable is likely saab_ajax_obj or saab_vars.
    • Hypothesis: The key is likely nonce or saab_nonce.
  2. Trigger Shortcode: The plugin likely uses a shortcode to display booking forms. Based on the slug, the shortcode is likely [smart_appointment_booking] or [saab_form].
  3. Setup:
    • Create a page containing the suspected shortcode: wp post create --post_type=page --post_status=publish --post_content='[smart_appointment_booking]'
  4. Extraction:
    • Navigate to the page as the Subscriber user.
    • Use browser_eval to find the nonce:
      browser_eval("window.saab_ajax_obj?.nonce || window.saab_vars?.security")

5. Exploitation Strategy

  1. Login: Authenticate as a Subscriber user using the browser_navigate and browser_type tools.
  2. Obtain Nonce: Follow the strategy in Section 4 to retrieve the valid nonce for the saab_save_form_data action.
  3. Craft Payload: Use a standard XSS payload wrapped in a JSON structure if the plugin expects serialized data, or as a direct POST parameter.
    • Target Parameter: form_data or saab_data.
    • Payload: {"label": "<script>alert(document.domain)</script>", "placeholder": "test"} (or similar attribute arrays).
  4. Execute HTTP Request:
    POST /wp-admin/admin-ajax.php HTTP/1.1
    Content-Type: application/x-www-form-urlencoded
    
    action=saab_save_form_data&security=[NONCE]&data=[XSS_PAYLOAD]
    
  5. Trigger XSS: Navigate to the page where the booking form is displayed or to the plugin's admin settings page as an administrator.

6. Test Data Setup

  1. User: Create a subscriber user: wp user create victim_subscriber sub@example.com --role=subscriber --user_pass=password123.
  2. Page: Create a page for the form: wp post create --post_type=page --post_title="Booking Page" --post_status=publish --post_content='[smart_appointment_booking]'.
  3. Plugin Activation: Ensure smart-appointment-booking is active.

7. Expected Results

  • The AJAX request should return a success response (e.g., {"success": true} or 1).
  • When an administrator visits the "Booking Page" or the plugin settings, an alert box with the document domain should appear.
  • The malicious script should be visible in the page source, unescaped within an attribute or label tag.

8. Verification Steps

  1. Check Database: Use WP-CLI to verify the stored payload:
    wp option get saab_form_settings (substitute saab_form_settings with the actual option name found during research).
  2. DOM Check: Use browser_eval to check for the presence of the payload in the DOM after the exploit:
    browser_eval("document.body.innerHTML.includes('<script>alert')")

9. Alternative Approaches

  • Missing Nonce: If no nonce check is performed, attempt the exploit without the security or nonce parameter.
  • Admin-Only Trigger: If the XSS does not fire on the frontend, check the admin dashboard booking list or form editor.
  • Attribute Breakout: If the input is placed inside an attribute (e.g., value="..."), use a breakout payload: " onmouseover="alert(1).
  • JSON Injection: If the input is part of a JSON blob in a hidden field, try: {"id": "1", "name": "test\"};alert(1);//"} .
Research Findings
Static analysis — not yet PoC-verified

Summary

The Smart Appointment & Booking plugin for WordPress is vulnerable to Stored Cross-Site Scripting via the saab_save_form_data AJAX action due to a lack of input sanitization and output escaping on user-supplied configuration data. Authenticated attackers with Subscriber-level privileges can inject arbitrary scripts that execute when a user or administrator visits the booking form or its settings page.

Vulnerable Code

// File: includes/class-ajax.php (Inferred from research plan)
add_action('wp_ajax_saab_save_form_data', 'saab_save_form_data');

function saab_save_form_data() {
    // Missing capability check and input sanitization
    $form_data = $_POST['form_data']; 
    update_option('saab_form_settings', $form_data);
    wp_send_json_success();
}

---

// File: includes/class-frontend.php (Inferred from research plan source analysis)
function render_saab_form() {
    $settings = get_option('saab_form_settings');
    // Outputting data-config without proper escaping allows for XSS attribute breakout or script injection
    echo "<div class='saab-container' data-config='" . $settings . "'></div>";
}

Security Fix

--- a/includes/class-ajax.php
+++ b/includes/class-ajax.php
@@ -1,6 +1,10 @@
 function saab_save_form_data() {
+    check_ajax_referer('saab_nonce', 'security');
+    if (!current_user_can('manage_options')) {
+        wp_send_json_error('Unauthorized');
+    }
-    $form_data = $_POST['form_data'];
+    $form_data = wp_kses_post($_POST['form_data']);
     update_option('saab_form_settings', $form_data);
     wp_send_json_success();
 }

Exploit Outline

1. Log in as a Subscriber user. 2. Access the site frontend to identify the localized JavaScript object (e.g., saab_ajax_obj or saab_vars) and extract the security nonce required for AJAX requests. 3. Construct a POST request to /wp-admin/admin-ajax.php with the 'action' parameter set to 'saab_save_form_data', the extracted nonce, and a malicious payload containing an XSS script (e.g., <script>alert(document.domain)</script>) within the 'form_data' parameter. 4. Submit the request to save the malicious script into the plugin's settings stored in the database. 5. Navigate to any page where the booking form shortcode is rendered or to the plugin's admin dashboard to trigger the script execution.

Check if your site is affected.

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