CVE-2026-11600

Envo's Templates & Widgets for Elementor and WooCommerce <= 1.4.26 - Missing Authorization to Authenticated (Author+) Private Content Disclosure via Envo Tabs Widget 'templates' Setting

mediumMissing Authorization
4.3
CVSS Score
4.3
CVSS Score
medium
Severity
1.4.27
Patched in
1d
Time to patch

Description

The Envo's Templates & Widgets for Elementor and WooCommerce plugin for WordPress is vulnerable to unauthorized access of data due to a missing authorization check on the Envo Tabs (and Off Canvas) widget's template rendering in versions up to, and including, 1.4.26. The render() method of the Tabs widget passes a user-controlled template/post ID directly to Elementor's get_builder_content_for_display() without verifying the referenced post's status (published/private/draft) or the visitor's authorization to view it. This makes it possible for authenticated attackers, with Author-level access and above, to disclose the contents of private Elementor-driven pages and templates to anonymous visitors by configuring an Envo Tabs widget on a public post to reference the private content's ID (which can be supplied by editing the underlying Elementor widget JSON via the Elementor editor REST API).

CVSS Vector Breakdown

CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:N
Attack Vector
Network
Attack Complexity
Low
Privileges Required
Low
User Interaction
None
Scope
Unchanged
Low
Confidentiality
None
Integrity
None
Availability

Technical Details

Affected versions<=1.4.26
PublishedJuly 1, 2026
Last updatedJuly 2, 2026

What Changed in the Fix

Changes introduced in v1.4.27

Loading patch diff...

Source Code

WordPress.org SVN
Research Plan
Unverified

# Exploitation Research Plan: CVE-2026-11600 ## 1. Vulnerability Summary The **Envo's Templates & Widgets for Elementor and WooCommerce** plugin (<= 1.4.26) is vulnerable to **Missing Authorization** in the `Envo Tabs` and `Off Canvas` widgets. The widget's `render()` method takes a post/template I…

Show full research plan

Exploitation Research Plan: CVE-2026-11600

1. Vulnerability Summary

The Envo's Templates & Widgets for Elementor and WooCommerce plugin (<= 1.4.26) is vulnerable to Missing Authorization in the Envo Tabs and Off Canvas widgets. The widget's render() method takes a post/template ID from the widget's settings (configured in the Elementor editor) and passes it directly to Elementor's get_builder_content_for_display() function.

Crucially, the plugin fails to verify if the post ID being rendered is "Published" or if the current visitor has permission to view it. This allows an authenticated user with "Author" privileges (who can use Elementor to edit their own posts) to inject the ID of a "Private" or "Draft" post/template belonging to another user (e.g., an Administrator). When the Author's post is viewed by an anonymous visitor, the plugin renders the sensitive content of the private post.

2. Attack Vector Analysis

  • Entry Point: The render() method of the ETWWElementor\Modules\Tabs\Widgets\Tabs class (and similarly the Off Canvas widget).
  • Vulnerable Parameter: The templates setting within the Elementor widget JSON data.
  • Authentication: Requires Author-level access (or any role capable of using the Elementor Editor).
  • Payload: A JSON object representing an Elementor widget configuration where the templates setting is set to the ID of a private post/template.
  • Preconditions:
    1. A private post or Elementor template containing sensitive data must exist (target ID).
    2. The attacker must have permissions to create/edit a post with Elementor.

3. Code Flow

  1. Configuration Phase (Authenticated Author):

    • The Author edits a post using Elementor.
    • The Author adds an etww-tabs widget.
    • The Author saves the post. The configuration is stored in the _elementor_data post meta.
    • Using the WordPress REST API or Elementor Editor API, the Author modifies the templates value in the JSON payload to point to a private post ID (e.g., ID 1337).
  2. Rendering Phase (Anonymous Visitor):

    • A visitor requests the URL of the Author's post.
    • WordPress initializes Elementor, which calls ETWWElementor\Modules\Tabs\Widgets\Tabs::render().
    • render() retrieves settings via $this->get_settings_for_display().
    • The code (inferred from patch) executes:
      echo Plugin::$instance->frontend->get_builder_content_for_display( $settings['templates'] );
    • get_builder_content_for_display() fetches the post by ID and renders its content regardless of status (Private/Draft) because the authorization check is missing in the caller (Tabs widget).

4. Nonce Acquisition Strategy

The exploit involves two stages: one authenticated (to set up the payload) and one unauthenticated (to trigger the disclosure).

Authenticated Stage (Author)

To save the malicious widget configuration, the Author needs a REST API nonce.

  1. Navigate to the Post Editor: Access the Elementor editor for a post the Author owns.
  2. Extract Nonce: The nonce for the WordPress REST API is typically localized as wpApiSettings.nonce.
  3. JS Execution:
    browser_eval("wpApiSettings.nonce")

5. Exploitation Strategy

Step 1: Discover Target ID

The attacker needs the ID of the private post. In a real-world scenario, this might be brute-forced or found via other info leaks. For this PoC, we will assume the ID is known after setup.

Step 2: Inject Malicious Widget (Authenticated)

As the Author, send a request to update the post's Elementor data.

  • Endpoint: POST /wp-json/wp/v2/posts/{POST_ID} (Standard WP REST API) or POST /wp-json/elementor/v1/editor-data
  • Method: POST
  • Headers:
    • X-WP-Nonce: [NONCE]
    • Content-Type: application/json
  • Payload:
    The _elementor_data meta field must contain a JSON string. The crucial part is the etww-tabs widget:
    [
      {
        "id": "random_id",
        "elType": "widget",
        "widgetType": "etww-tabs",
        "settings": {
          "tabs": [
            {
              "tab_title": "Exploit Tab",
              "source": "template",
              "templates": "TARGET_PRIVATE_POST_ID"
            }
          ]
        }
      }
    ]
    

Step 3: Disclosure (Unauthenticated)

  • Endpoint: GET /?p={AUTHOR_POST_ID}
  • Action: Access the post as an anonymous user.
  • Result: The content of the private post (TARGET_PRIVATE_POST_ID) will be rendered within the Tab content.

6. Test Data Setup

  1. Administrator User:
    • Create a private post (ID X) with the content: "SECRET_DATA_INTERNAL_ONLY".
    • Ensure the post status is private.
  2. Author User:
    • Create a user with the Author role.
    • Create a public post (ID Y) and enable Elementor for it.
  3. Plugin Config:
    • Ensure "Envo's Templates & Widgets" is active.

7. Expected Results

  • When accessing GET /?p=Y (the Author's post) as an anonymous user, the string "SECRET_DATA_INTERNAL_ONLY" should be visible in the HTML response inside the etww-tabs container.
  • Normally, this content would be inaccessible to anonymous users and Authors.

8. Verification Steps

  1. Check Status: Use wp post get X --field=post_status to confirm the target post is indeed private.
  2. Check Response: Search the HTML of the Author's post for the secret string:
    http_request("GET", "http://localhost:8080/?p=Y") -> Verify presence of "SECRET_DATA_INTERNAL_ONLY".

9. Alternative Approaches

If updating via REST API is blocked, the attacker can use admin-ajax.php with the action elementor_ajax to save editor data:

  • Action: elementor_ajax
  • Data: actions={"save_builder":{"action":"save_builder","data":{"status":"publish","elements":[...]}}}
  • Nonce: Required from window.elementorConfig.api_nonce.

If the Tabs widget is not available, try the etww-off-canvas widget, as the description indicates it is also vulnerable. The setting name might be template_id or templates (check register_controls in modules/off-canvas/widgets/off-canvas.php if available).

Research Findings
Static analysis — not yet PoC-verified

Summary

The Envo Tabs widget in Envo's Templates & Widgets for Elementor and WooCommerce fails to verify the status or permissions of templates it renders via post IDs. This allows authenticated users with Author-level access to inject private post IDs into the widget settings, resulting in the disclosure of sensitive private content to anonymous visitors.

Vulnerable Code

// modules/tabs/widgets/tabs.php line 1267
                        } else if ('template' == $item['source'] && ('0' != $item['templates'] && !empty($item['templates']))) {
                            echo Plugin::instance()->frontend->get_builder_content_for_display($item['templates']);
                        }

Security Fix

--- /home/deploy/wp-safety.org/data/plugin-versions/envo-elementor-for-woocommerce/1.4.26/modules/tabs/widgets/tabs.php	2026-05-27 06:33:38.000000000 +0000
+++ /home/deploy/wp-safety.org/data/plugin-versions/envo-elementor-for-woocommerce/1.4.27/modules/tabs/widgets/tabs.php	2026-06-19 10:52:20.000000000 +0000
@@ -1265,7 +1265,9 @@
                         if ('custom' == $item['source'] && !empty($item['tab_content'])) {
                             echo $this->parse_text_editor($item['tab_content']);
                         } else if ('template' == $item['source'] && ('0' != $item['templates'] && !empty($item['templates']))) {
-                            echo Plugin::instance()->frontend->get_builder_content_for_display($item['templates']);
+							if (get_post_status($item['templates']) === 'publish') {
+								echo Plugin::instance()->frontend->get_builder_content_for_display($item['templates']);
+							}
                         }
                         ?>
                     </div>

Exploit Outline

The exploit is executed by an authenticated attacker with Author-level privileges or higher. 1. The attacker identifies the ID of a private post or Elementor template containing sensitive data. 2. The attacker creates or edits a post they own using the Elementor editor and adds the 'Envo Tabs' (etww-tabs) widget. 3. Using the WordPress REST API (targeting the post's meta) or the Elementor Editor AJAX API (action: 'elementor_ajax'), the attacker manually updates the widget configuration JSON in the '_elementor_data' field. They set the 'source' to 'template' and the 'templates' parameter to the ID of the target private post. 4. Once the post is saved, the attacker or any anonymous visitor navigates to the public URL of the Author's post. 5. The 'render()' method in the Tabs widget fetches the private post content via 'get_builder_content_for_display()' and displays it on the page because it lacks a check for 'publish' status or user authorization.

Check if your site is affected.

Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.