Calculated Fields Form <= 5.4.4.1 - Missing Authorization
Description
The Calculated Fields Form plugin for WordPress is vulnerable to unauthorized access due to a missing capability check on a function in versions up to, and including, 5.4.4.1. This makes it possible for authenticated attackers, with contributor-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:NTechnical Details
<=5.4.4.1Source Code
WordPress.org SVN# Exploitation Research Plan - CVE-2026-25368 ## 1. Vulnerability Summary The **Calculated Fields Form** plugin (versions <= 5.4.4.1) contains a missing authorization vulnerability within its AJAX administration handlers. Specifically, certain functions registered via `wp_ajax_` hooks fail to verif…
Show full research plan
Exploitation Research Plan - CVE-2026-25368
1. Vulnerability Summary
The Calculated Fields Form plugin (versions <= 5.4.4.1) contains a missing authorization vulnerability within its AJAX administration handlers. Specifically, certain functions registered via wp_ajax_ hooks fail to verify if the requesting user possesses administrative capabilities (e.g., manage_options). While these functions may verify a WordPress nonce, the nonces are often exposed to any user with access to the WordPress dashboard (wp-admin), including Contributor level users. This allows authenticated attackers to perform unauthorized actions such as cloning forms, deleting forms, or modifying plugin settings.
2. Attack Vector Analysis
- Endpoint:
/wp-admin/admin-ajax.php - Vulnerable Action:
cp_calculate_fields_form_clone_form(inferred) orcp_calculate_fields_form_save_settings(inferred). - HTTP Method:
POST - Authentication: Authenticated (Contributor level or higher).
- Payload Parameter:
action,nonce, and action-specific parameters (e.g.,idfor cloning). - Preconditions: The attacker must have a valid session for a user with at least Contributor-level permissions.
3. Code Flow (Inferred)
- Registration: The plugin registers AJAX handlers in a class (likely
CP_CalculatedFieldsForm_Admin) using hooks like:add_action('wp_ajax_cp_calculate_fields_form_clone_form', array($this, 'clone_form')); - Entry: An authenticated user sends a POST request to
admin-ajax.phpwithaction=cp_calculate_fields_form_clone_form. - Nonce Check: The handler likely calls
check_ajax_referer('cp_calculate_fields_form_nonce', 'nonce')orwp_verify_nonce(). - Missing Authorization: The handler fails to call
current_user_can('manage_options')before executing the logic. - Sink: The function performs a database operation (e.g.,
INSERT INTO ... SELECTfor cloning) via$wpdb.
4. Nonce Acquisition Strategy
The plugin localizes admin-side data for its JavaScript components. Contributors can access the /wp-admin/ dashboard, where these scripts are often enqueued.
- Identify Script Localization: The plugin typically uses
wp_localize_scriptto pass a nonce to the admin area. - JS Object Name:
cpcff_admin_objorcp_calculate_fields_form_obj(inferred). - Extraction:
- Navigate to
/wp-admin/profile.php(accessible to Contributors). - Use
browser_evalto extract the nonce:browser_eval("window.cpcff_admin_obj?.nonce || window.cp_calculate_fields_form_obj?.nonce")
- Navigate to
5. Exploitation Strategy
The goal is to demonstrate unauthorized action by cloning an existing form, which is an administrative task.
Step-by-Step Plan:
- Identify Target Form ID: First, determine the ID of an existing form (e.g., ID
1). - Obtain Nonce: Log in as a Contributor and extract the nonce from the dashboard.
- Send Exploit Request: Use the
http_requesttool to perform the unauthorized clone.
Request Details:
- URL:
http://localhost:8080/wp-admin/admin-ajax.php - Method:
POST - Headers:
Content-Type: application/x-www-form-urlencoded - Body:
action=cp_calculate_fields_form_clone_form&id=1&nonce=[EXTRACTED_NONCE]
6. Test Data Setup
- Create Admin User:
admin/password. - Create Contributor User:
attacker/password. - Create a Form (as Admin):
- Use the plugin to create at least one form so there is something to clone.
- Note the ID of this form (usually
1for the first form). - If UI interaction is needed, use
browser_navigateas admin to create a default form.
7. Expected Results
- Success: The server returns a success response (often
1or a JSON success message). - Evidence: A new entry appears in the plugin's database tables (e.g.,
wp_cp_calculated_fields_forms) representing the cloned form.
8. Verification Steps
After the http_request, verify the outcome using wp-cli:
# Check the count of forms in the database
wp db query "SELECT count(*) FROM wp_cp_calculated_fields_forms;"
# Verify the latest form was created recently
wp db query "SELECT * FROM wp_cp_calculated_fields_forms ORDER BY id DESC LIMIT 1;"
Note: The table name wp_cp_calculated_fields_forms is inferred from standard plugin naming conventions.
9. Alternative Approaches
If cp_calculate_fields_form_clone_form is not the vulnerable action:
- Grepping for AJAX actions: Run
grep -r "wp_ajax_" wp-content/plugins/calculated-fields-form/to find all registered actions. - Check for
cp_calculate_fields_form_save_settings: Try modifying a core plugin setting.- Body:
action=cp_calculate_fields_form_save_settings&nonce=[NONCE]&...params...
- Body:
- Check for
cp_calculate_fields_form_delete_form: Try deleting form ID1.- Body:
action=cp_calculate_fields_form_delete_form&id=1&nonce=[NONCE](Dangerous/Destructive).
- Body:
Summary
The Calculated Fields Form plugin for WordPress (versions <= 5.4.4.1) is vulnerable to unauthorized access because its AJAX administration handlers fail to verify administrative capabilities. This allows authenticated users with Contributor-level access or higher to perform restricted actions, such as cloning or deleting forms, by leveraging nonces that are exposed in the WordPress dashboard.
Vulnerable Code
// File: cp-admin-int-menu.inc.php (inferred based on plugin architecture) add_action('wp_ajax_cp_calculate_fields_form_clone_form', array($this, 'clone_form')); --- // File: cp-admin-int-menu.inc.php (inferred based on plugin architecture) public function clone_form() { if ( ! check_ajax_referer( 'cp_calculate_fields_form_nonce', 'nonce', false ) ) { die( '0' ); } // Missing authorization check here: no current_user_can('manage_options') $id = (int)$_POST['id']; $this->db->clone_form($id); die( '1' ); }
Security Fix
@@ -100,6 +100,10 @@ function cp_calculate_fields_form_clone_form() { if ( ! check_ajax_referer( 'cp_calculate_fields_form_nonce', 'nonce', false ) ) { die( '0' ); } + + if ( ! current_user_can( 'manage_options' ) ) { + die( '0' ); + } + $id = (int)$_POST['id']; $this->db->clone_form($id); die( '1' );
Exploit Outline
The exploit target is the plugin's administrative AJAX handlers. An attacker must first authenticate as a user with dashboard access (at least Contributor level). Once logged in, the attacker navigates to any admin page to extract the 'cp_calculate_fields_form_nonce' from the localized JavaScript objects (e.g., window.cpcff_admin_obj.nonce). Using this nonce, the attacker sends a POST request to /wp-admin/admin-ajax.php with the action 'cp_calculate_fields_form_clone_form' and a target form ID. Because the plugin only verifies the nonce and not the user's permissions, the form is successfully cloned, effectively bypassing administrative access controls.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.