CVE-2025-69388

Cliengo – Chatbot <= 3.0.4 - Missing Authorization

mediumMissing Authorization
4.3
CVSS Score
4.3
CVSS Score
medium
Severity
3.0.5
Patched in
66d
Time to patch

Description

The Cliengo – Chatbot plugin for WordPress is vulnerable to unauthorized access due to a missing capability check on a function in versions up to, and including, 3.0.4. This makes it possible for authenticated attackers, with subscriber-level access and above, to perform an unauthorized action.

CVSS Vector Breakdown

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

Technical Details

Affected versions<=3.0.4
PublishedFebruary 9, 2026
Last updatedApril 15, 2026
Affected plugincliengo

What Changed in the Fix

Changes introduced in v3.0.5

Loading patch diff...

Source Code

WordPress.org SVN
Research Plan
Unverified

` (inside `Cliengo_Admin`) was: ```php add_menu_page('Cliengo', 'Cliengo', 'read', 'cliengo', array($this, 'display_page')); ``` Then a Subscriber could see the page. And the page `display_page` would include: `include_once 'partials/cliengo-admin-disp…

Show full research plan

(insideCliengo_Admin) was: ```php add_menu_page('Cliengo', 'Cliengo', 'read', 'cliengo', array($this, 'display_page')); ``` Then a Subscriber could see the page. And the page display_pagewould include: include_once 'partials/cliengo-admin-display.php'; Which would output: ```php <input type="hidden" id="update_chatbot_token_nonce" ... value="<?php echo wp_create_nonce('update_chatbot_token_action'); ?>" /> ``` So a Subscriber *can* get the nonce. But they still fail thecurrent_user_can('manage_options')check inupdate_chatbot_token`.

    Wait! Does EVERY function have the `current_user_can` check?
    `update_chatbot_token` - Yes.
    `update_chatbot_position` - Yes.
    `update_session` - Yes.
    `wordpress_login` - **NO**.
    `wp_registration` - **Likely NO** (since it's registered similarly to `wordpress_login` and missing from snippet).
    `restore_session` - **NO**.

    So `wordpress_login`, `wp_registration`, and `restore_session` are the missing ones.
    `restore_session` is `C:
Research Findings
Static analysis — not yet PoC-verified

Summary

The Cliengo – Chatbot plugin for WordPress is vulnerable to unauthorized access and potential information disclosure due to missing capability checks on several AJAX handlers. This allows authenticated attackers, such as Subscribers, to perform actions like restoring sessions (leaking account tokens), attempting Cliengo account logins, and registering new accounts.

Vulnerable Code

// admin/class-cliengo-form.php line 71
  public function restore_session() {
    $account = get_option( 'cliengo_session' );
    $session = array(
      'token' => stripslashes( get_option( 'cliengo_chatbot_token' ) ),
      'account' => $account != null ? json_decode(stripslashes($account)) : '',
      'position' => stripslashes( get_option( 'cliengo_chatbot_position' ) )
    );

    echo wp_json_encode($session);
    wp_die();
  }

---

// admin/class-cliengo-form.php line 154
  public function wordpress_login()
  {
    if ( ! isset( $_POST['wordpress_login_nonce'] ) || ! wp_verify_nonce( $_POST['wordpress_login_nonce'], 'wordpress_login_action' ) ) {
      wp_die('Security Error: Security check failed. Please reload the page and try again.');
    }

    $api_host = Cliengo_Form::PROD_ENV ? 'https://api.cliengo.com' : 'https://api.stagecliengo.com';
    $body = array('username' => $_POST['username'], 'password' => $_POST['password']);
    // ... (rest of function)

Security Fix

diff -ru /home/deploy/wp-safety.org/data/plugin-versions/cliengo/3.0.4/admin/class-cliengo-form.php /home/deploy/wp-safety.org/data/plugin-versions/cliengo/3.0.5/admin/class-cliengo-form.php
--- /home/deploy/wp-safety.org/data/plugin-versions/cliengo/3.0.4/admin/class-cliengo-form.php	2024-07-15 19:44:10.000000000 +0000
+++ /home/deploy/wp-safety.org/data/plugin-versions/cliengo/3.0.5/admin/class-cliengo-form.php	2026-03-17 18:43:42.000000000 +0000
@@ -74,6 +93,12 @@
    * Fetches and returns all session variables
    */
   public function restore_session() {
+    if ( ! current_user_can( 'manage_options' ) ) {
+      wp_die( 'Error: You do not have sufficient permissions to perform this action.' );
+    }
+
+    check_ajax_referer( 'restore_session_action', 'restore_session_nonce' );
+
     $account = get_option( 'cliengo_session' );
     $session = array( 
@@ -153,9 +175,13 @@
    */
   public function wordpress_login()
   {
-    if ( ! isset( $_POST['wordpress_login_nonce'] ) || ! wp_verify_nonce( $_POST['wordpress_login_nonce'], 'wordpress_login_action' ) ) {
-      wp_die('Security Error: Security check failed. Please reload the page and try again.');
+    if ( ! current_user_can( 'manage_options' ) ) {
+      wp_die( 'Error: You do not have sufficient permissions to perform this action. Please contact the site administrator.' );
     }
 
+    check_ajax_referer( 'wordpress_login_action', 'wordpress_login_nonce' );
+
+    $username = isset( $_POST['username'] ) ? sanitize_email( wp_unslash( $_POST['username'] ) ) : '';
+    $password = isset( $_POST['password'] ) ? wp_unslash( $_POST['password'] ) : '';
+
     $api_host = Cliengo_Form::PROD_ENV ? 'https://api.cliengo.com' : 'https://api.stagecliengo.com';
-    $body = array('username' => $_POST['username'], 'password' => $_POST['password']);
+    $body = array( 'username' => $username, 'password' => $password );

Exploit Outline

The exploit methodology involves an authenticated attacker with low-level privileges (e.g., Subscriber) performing the following steps: 1. **Access the Admin Dashboard**: Login to the WordPress site as a Subscriber. 2. **Retrieve Nonces**: Visit the Cliengo configuration page (registered with the 'read' capability). Inspect the HTML source to find hidden input fields containing nonces for various actions, such as `wordpress_login_nonce`, `update_session_nonce`, and `wp_registration_nonce`. 3. **Execute Unauthorized AJAX Action**: Send a POST request to `/wp-admin/admin-ajax.php`. * To leak the chatbot token and session data, use the `action=restore_session` parameter. Since version 3.0.4 lacked both capability and nonce checks for this specific action, the server will return the session JSON. * To attempt account operations, use actions like `wordpress_login` or `wp_registration` while providing the stolen nonces from Step 2. Even though these actions have nonce checks, they lack a `current_user_can('manage_options')` check, allowing the request to proceed if a valid nonce (which the plugin leaked to the Subscriber) is provided.

Check if your site is affected.

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