Easy Form <= 2.7.9 - Missing Authorization
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:NTechnical Details
What Changed in the Fix
Changes introduced in v2.8.0
Source Code
WordPress.org SVN# 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_initorwp_ajax_nopriv_ays_form_admin_ajax - Vulnerable Action:
ays_form_actionoractionparameter triggers a sensitive method (e.g.,duplicate_form) without authorization. - Authentication: None required (Unauthenticated).
- Preconditions: A form
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
@@ -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 ); @@ -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.