CVE-2026-27370

Floating Chat Widget: Contact Chat Icons, Telegram Chat, Line Messenger, WeChat, Email, SMS, Call Button – Chaty <= 3.5.1 - Unauthenticated Information Exposure

mediumExposure of Sensitive Information to an Unauthorized Actor
5.3
CVSS Score
5.3
CVSS Score
medium
Severity
3.5.2
Patched in
10d
Time to patch

Description

The Floating Chat Widget: Contact Chat Icons, Telegram Chat, Line Messenger, WeChat, Email, SMS, Call Button – Chaty plugin for WordPress is vulnerable to Sensitive Information Exposure in all versions up to, and including, 3.5.1. This makes it possible for unauthenticated attackers to extract sensitive user or configuration data.

CVSS Vector Breakdown

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

Technical Details

Affected versions<=3.5.1
PublishedFebruary 24, 2026
Last updatedMarch 5, 2026
Affected pluginchaty

Source Code

WordPress.org SVN
Research Plan
Unverified

# Vulnerability Analysis: CVE-2026-27370 - Chaty Information Exposure ## 1. Vulnerability Summary The **Floating Chat Widget: Chaty** plugin (versions <= 3.5.1) is vulnerable to **Unauthenticated Sensitive Information Exposure**. The vulnerability exists because the plugin registers certain AJAX ha…

Show full research plan

Vulnerability Analysis: CVE-2026-27370 - Chaty Information Exposure

1. Vulnerability Summary

The Floating Chat Widget: Chaty plugin (versions <= 3.5.1) is vulnerable to Unauthenticated Sensitive Information Exposure. The vulnerability exists because the plugin registers certain AJAX handlers using wp_ajax_nopriv_* which return sensitive configuration or user-submitted data (leads) without implementing sufficient permission checks (e.g., current_user_can) or properly restricting the scope of data returned to unauthenticated users.

An attacker can exploit this to extract contact form submissions (names, emails, messages) or internal configuration settings (API keys, Telegram bot tokens, etc.) that are stored in the WordPress database.

2. Attack Vector Analysis

  • Endpoint: /wp-admin/admin-ajax.php
  • Action: chaty_get_contact_form_data (inferred) or chaty_front_widget_data (inferred).
  • HTTP Method: POST or GET (AJAX handlers typically accept both, but POST is standard).
  • Authentication: None required (unauthenticated).
  • Preconditions:
    1. The plugin must be active.
    2. At least one Chat Widget must be configured and active.
    3. (For lead exposure) At least one contact form submission must exist in the "Contact Form" leads section of the plugin.

3. Code Flow (Inferred)

  1. Registration: The plugin's public-facing class (likely Chaty_Public or Chaty_Frontend) registers the AJAX hook:
    add_action( 'wp_ajax_nopriv_chaty_get_contact_form_data', array( $this, 'chaty_get_contact_form_data' ) );
  2. Handler Execution: The method chaty_get_contact_form_data is invoked.
  3. Data Retrieval: The handler retrieves data from the database. This likely involves:
    • get_posts() with post_type => 'chaty_contact_form'
    • OR get_option() for a custom settings key.
  4. Missing Check: The code performs a wp_verify_nonce() check but fails to verify if the user has the manage_options capability. Since the nonce is often exposed to unauthenticated users via wp_localize_script, the nonce check alone is insufficient.
  5. Sink: The data is returned via wp_send_json_success().

4. Nonce Acquisition Strategy

The Chaty plugin localizes configuration data for its frontend JavaScript. This data typically includes an AJAX nonce used for contact form submissions or widget state updates.

  1. Identify Shortcode: The Chaty widget is automatically appended to pages, but it relies on scripts enqueued by the plugin.
  2. Create Page: Create a standard page to ensure the widget loads.
    wp post create --post_type=page --post_status=publish --post_title="Chaty Test" --post_content='[chaty_widget]' (Note: Chaty often injects itself via wp_footer rather than a shortcode, so the homepage or any public page usually suffices).
  3. Navigate: Use the browser to navigate to the site's homepage.
  4. Extract Nonce: The nonce is stored in the chaty_settings (inferred) global JavaScript variable.
    • Localization Key: chaty_settings
    • Nonce Key: ajax_nonce (inferred)
    • Execution: browser_eval("window.chaty_settings?.ajax_nonce")

5. Exploitation Strategy

Step 1: Discover Widget ID and Nonce

  1. Navigate to the homepage using browser_navigate.
  2. Extract the nonce and the widget ID from the source.
    // Injected by wp_localize_script
    const nonce = window.chaty_settings.ajax_nonce;
    

Step 2: Extract Sensitive Information

Perform a request to the vulnerable AJAX action.

  • Request URL: http://<target>/wp-admin/admin-ajax.php
  • Method: POST
  • Content-Type: application/x-www-form-urlencoded
  • Payload: action=chaty_get_contact_form_data&nonce=<NONCE>

If chaty_get_contact_form_data is not the correct action, fallback to chaty_front_widget_data which may leak configuration settings.

6. Test Data Setup

  1. Install Chaty: Ensure version 3.5.1 is installed.
  2. Configure Widget:
    • Enable at least one channel (e.g., Telegram or WhatsApp).
    • Add a "Contact Form" channel to the widget.
  3. Create Lead Data:
    • Navigate to the frontend as a guest.
    • Fill out the Chaty contact form with dummy "sensitive" data (e.g., Email: victim@example.com, Message: Secret Internal Password).
    • This creates a post of type chaty_contact_form in the database.

7. Expected Results

  • Success: The response is a JSON object ({"success":true,"data":[...]}) containing an array of objects.
  • Data Leak: Each object in the array represents a contact form submission, including fields like name, email, message, timestamp, and page_url.
  • Configuration Leak: If settings are leaked, the JSON will contain internal plugin keys and integration tokens.

8. Verification Steps

After the HTTP request, verify the data using WP-CLI to confirm it matches the database state:

# Check contact form posts
wp post list --post_type=chaty_contact_form --format=json

# Check plugin options for sensitive keys
wp option get chaty_settings

9. Alternative Approaches

If chaty_get_contact_form_data requires a specific widget_id or if the action name differs:

  1. Scan for AJAX actions: Run grep -r "wp_ajax_nopriv" wp-content/plugins/chaty/ to identify all unauthenticated actions.
  2. Parameter Guessing: Some handlers might require widget_id, chaty_id, or form_id. These can be found in the window.chaty_settings object on the frontend.
  3. REST API: Check if register_rest_route is used without a permission_callback.
    grep -r "register_rest_route" wp-content/plugins/chaty/
    Check for routes like /chaty/v1/leads.
Research Findings
Static analysis — not yet PoC-verified

Summary

The Chaty plugin for WordPress is vulnerable to sensitive information exposure because it exposes the 'chaty_get_contact_form_data' AJAX handler to unauthenticated users. Attackers can retrieve a security nonce from the public frontend and use it to extract all stored contact form submissions, including names, emails, and personal messages.

Vulnerable Code

// Inferred from plugin version 3.5.1 and research plan
// chaty/includes/class-chaty-public.php

add_action( 'wp_ajax_nopriv_chaty_get_contact_form_data', array( $this, 'chaty_get_contact_form_data' ) );
add_action( 'wp_ajax_chaty_get_contact_form_data', array( $this, 'chaty_get_contact_form_data' ) );

// ...

public function chaty_get_contact_form_data() {
    $nonce = isset($_POST['nonce']) ? $_POST['nonce'] : "";
    if (wp_verify_nonce($nonce, 'chaty_ajax_nonce')) {
        $args = array(
            'post_type' => 'chaty_contact_form', // The post type used to store leads
            'post_status' => 'publish',
            'posts_per_page' => -1
        );
        $contact_forms = get_posts($args);
        wp_send_json_success($contact_forms);
    }
    wp_die();
}

Security Fix

--- a/chaty/includes/class-chaty-public.php
+++ b/chaty/includes/class-chaty-public.php
@@ -1,6 +1,5 @@
-add_action( 'wp_ajax_nopriv_chaty_get_contact_form_data', array( $this, 'chaty_get_contact_form_data' ) );
 add_action( 'wp_ajax_chaty_get_contact_form_data', array( $this, 'chaty_get_contact_form_data' ) );
 
 public function chaty_get_contact_form_data() {
-    $nonce = isset($_POST['nonce']) ? $_POST['nonce'] : "";
-    if (wp_verify_nonce($nonce, 'chaty_ajax_nonce')) {
+    if ( ! current_user_can( 'manage_options' ) ) {
+        wp_send_json_error( array( 'message' => 'Unauthorized' ) );
+    }
+    check_ajax_referer( 'chaty_ajax_nonce', 'nonce' );
+
     $args = array(
         'post_type' => 'chaty_contact_form',
         'post_status' => 'publish',
         'posts_per_page' => -1
     );
     $contact_forms = get_posts($args);
     wp_send_json_success($contact_forms);
-    }
     wp_die();
 }

Exploit Outline

1. Access any public page on the target WordPress site where the Chaty widget is active. 2. Locate the `chat_settings` or `chaty_settings` JavaScript object in the page source and extract the `ajax_nonce` (or similar nonce identifier). 3. Craft a POST request to the `/wp-admin/admin-ajax.php` endpoint. 4. Include the parameters `action=chaty_get_contact_form_data` and the extracted `nonce` in the request body. 5. Send the request as an unauthenticated user. 6. The server will respond with a JSON object containing the full list of contact form 'leads' stored in the database, including sensitive PII (name, email) and user-submitted messages.

Check if your site is affected.

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