CVE-2026-32332

Easy Form <= 2.7.9 - Missing Authorization

mediumMissing Authorization
5.3
CVSS Score
5.3
CVSS Score
medium
Severity
2.8.0
Patched in
66d
Time to patch

Description

The Easy Form plugin for WordPress is vulnerable to unauthorized access due to a missing capability check on a function in versions up to, and including, 2.7.9. 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<=2.7.9
PublishedFebruary 9, 2026
Last updatedApril 15, 2026
Affected plugineasy-form

What Changed in the Fix

Changes introduced in v2.8.0

Loading patch diff...

Source Code

WordPress.org SVN
Research Plan
Unverified

# Vulnerability Analysis: CVE-2026-32332 The **Easy Form** plugin (versions <= 2.7.9) is vulnerable to **Missing Authorization**, allowing unauthenticated attackers to perform unauthorized actions. The vulnerability likely stems from a handler hooked to `admin_init` (which executes for all requests…

Show full research plan

Vulnerability Analysis: CVE-2026-32332

The Easy Form plugin (versions <= 2.7.9) is vulnerable to Missing Authorization, allowing unauthenticated attackers to perform unauthorized actions. The vulnerability likely stems from a handler hooked to admin_init (which executes for all requests to /wp-admin/admin-ajax.php, including unauthenticated ones) or a wp_ajax_nopriv_ action that lacks a current_user_can() check.

Given the CVSS vector CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:N, the impact is limited to Integrity (Low) with No Confidentiality impact. This suggests the unauthorized action involves modifying or deleting non-sensitive data (e.g., duplicating a form, deleting an entry, or resetting statistics) rather than exporting data.

Attack Vector Analysis

  • Endpoint: /wp-admin/admin-ajax.php (or potentially /wp-admin/admin-post.php)
  • Hook: admin_init or wp_ajax_nopriv_ays_form_admin_ajax
  • Vulnerable Action: ays_form_action or action parameter triggers a sensitive method (e.g., duplicate_form) without authorization.
  • Authentication: None required (Unauthenticated).
  • Preconditions: A form
Research Findings
Static analysis — not yet PoC-verified

Summary

The Easy Form plugin for WordPress is vulnerable to unauthorized access because it registers the 'ays_form_admin_ajax' AJAX handler for unauthenticated users and fails to perform capability checks or nonce verification. This allows unauthenticated attackers to execute arbitrary methods within the Ays_Form_Maker_Admin class by specifying the method name in the 'function' request parameter.

Vulnerable Code

// includes/class-ays-form-maker.php
// Registration of nopriv hook makes the handler accessible to unauthenticated users
$this->loader->add_action( 'wp_ajax_ays_form_admin_ajax', $plugin_admin, 'ays_form_admin_ajax' );
$this->loader->add_action( 'wp_ajax_nopriv_ays_form_admin_ajax', $plugin_admin, 'ays_form_admin_ajax' );

---

// admin/class-ays-form-maker-admin.php line 942
public function ays_form_admin_ajax() {
    $response = array(
        "status" => false
    );
    // phpcs:ignore WordPress.Security.NonceVerification.Recommended
    $function = isset($_REQUEST['function']) ? sanitize_text_field( wp_unslash( $_REQUEST['_ajax_nonce'] ) ) : null;

    if($function !== null){
        $response = array();
        if( is_callable( array( $this, $function ) ) ){
            $response = $this->$function();

            ob_end_clean();
            $ob_get_clean = ob_get_clean();
            echo json_encode( $response );
            wp_die();
        }
    }
    ob_end_clean();
    $ob_get_clean = ob_get_clean();
    echo json_encode( $response );
    wp_die();
}

Security Fix

diff -ru /home/deploy/wp-safety.org/data/plugin-versions/easy-form/2.7.9/admin/class-ays-form-maker-admin.php /home/deploy/wp-safety.org/data/plugin-versions/easy-form/2.8.0/admin/class-ays-form-maker-admin.php
--- /home/deploy/wp-safety.org/data/plugin-versions/easy-form/2.7.9/admin/class-ays-form-maker-admin.php	2025-11-19 13:03:58.000000000 +0000
+++ /home/deploy/wp-safety.org/data/plugin-versions/easy-form/2.8.0/admin/class-ays-form-maker-admin.php	2026-02-18 08:12:26.000000000 +0000
@@ -942,20 +942,56 @@
 		$response = array(
 			"status" => false
 		);
+
+		// Security Check 1: Verify user is logged in
+		if ( ! is_user_logged_in() ) {
+			ob_end_clean();
+			$ob_get_clean = ob_get_clean();
+			echo json_encode( $response );
+			wp_die();
+		}
+
+		// Security Check 2: Verify nonce
+		// phpcs:ignore WordPress.Security.NonceVerification.Recommended
+		$nonce = isset($_REQUEST['_ajax_nonce']) ? sanitize_text_field( wp_unslash( $_REQUEST['_ajax_nonce'] ) ) : '';
+		if ( ! wp_verify_nonce( $nonce, 'ays-form-maker-admin-ajax-nonce' ) ) {
+			ob_end_clean();
+			$ob_get_clean = ob_get_clean();
+			echo json_encode( $response );
+			wp_die();
+		}
+
+		// Security Check 3: Verify user has admin capabilities
+		if ( ! current_user_can( 'manage_options' ) ) {
+			ob_end_clean();
+			$ob_get_clean = ob_get_clean();
+			echo json_encode( $response );
+			wp_die();
+		}
+
+		// Get the function name from request
 		// phpcs:ignore WordPress.Security.NonceVerification.Recommended
 		$function = isset($_REQUEST['function']) ? sanitize_text_field( wp_unslash( $_REQUEST['function'] ) ) : null;
 
-		if($function !== null){
+		// Security Check 4: Whitelist allowed AJAX functions
+		$allowed_functions = array(
+			'ays_live_preivew_content',
+			'ays_form_entry_report',
+			'ays_form_add_form_template',
+			'deactivate_plugin_option',
+			'get_selected_posts'
+		);
+
+		if ( $function !== null && in_array( $function, $allowed_functions, true ) && is_callable( array( $this, $function ) ) ) {
 			$response = array();
-			if( is_callable( array( $this, $function ) ) ){
-				$response = $this->$function();
+			$response = $this->$function();
 
-				ob_end_clean();
-				$ob_get_clean = ob_get_clean();
-				echo json_encode( $response );
-				wp_die();
-			}
+			ob_end_clean();
+			$ob_get_clean = ob_get_clean();
+			echo json_encode( $response );
+			wp_die();
 		}
+
 		ob_end_clean();
 		$ob_get_clean = ob_get_clean();
 		echo json_encode( $response );
diff -ru /home/deploy/wp-safety.org/data/plugin-versions/easy-form/2.7.9/includes/class-ays-form-maker.php /home/deploy/wp-safety.org/data/plugin-versions/easy-form/2.8.0/includes/class-ays-form-maker.php
--- /home/deploy/wp-safety.org/data/plugin-versions/easy-form/2.7.9/includes/class-ays-form-maker.php
+++ /home/deploy/wp-safety.org/data/plugin-versions/easy-form/2.8.0/includes/class-ays-form-maker.php
@@ -248,7 +248,7 @@
 
 		// Admin AJAX action
 		$this->loader->add_action( 'wp_ajax_ays_form_admin_ajax', $plugin_admin, 'ays_form_admin_ajax' );
-		$this->loader->add_action( 'wp_ajax_nopriv_ays_form_admin_ajax', $plugin_admin, 'ays_form_admin_ajax' );
+		// Note: Removed wp_ajax_nopriv_ hook for security - requires authentication

Exploit Outline

The exploit target is the `admin-ajax.php` endpoint. An attacker sends a POST or GET request with the `action` parameter set to `ays_form_admin_ajax`. By providing a `function` parameter, the attacker can force the server to execute any public method within the `Ays_Form_Maker_Admin` class. No authentication or valid nonces are required. For example, an attacker could attempt to manipulate plugin options by targeting `deactivate_plugin_option` or generate reports via `ays_form_entry_report`.

Check if your site is affected.

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