[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$f_ed47IrdGshLjAhnMWlbB4JBd49ElyYw6MA83LjYdcc":3},{"id":4,"url_slug":5,"title":6,"description":7,"plugin_slug":8,"theme_slug":9,"affected_versions":10,"patched_in_version":11,"severity":12,"cvss_score":13,"cvss_vector":14,"vuln_type":15,"published_date":16,"updated_date":17,"references":18,"days_to_patch":20,"patch_diff_files":21,"patch_trac_url":9,"research_status":22,"research_verified":23,"research_rounds_completed":24,"research_plan":25,"research_summary":26,"research_vulnerable_code":27,"research_fix_diff":28,"research_exploit_outline":29,"research_model_used":30,"research_started_at":31,"research_completed_at":32,"research_error":9,"poc_status":9,"poc_video_id":9,"poc_summary":9,"poc_steps":9,"poc_tested_at":9,"poc_wp_version":9,"poc_php_version":9,"poc_playwright_script":9,"poc_exploit_code":9,"poc_has_trace":23,"poc_model_used":9,"poc_verification_depth":9,"poc_exploit_code_gated":23,"source_links":33},"CVE-2026-4659","unlimited-elements-for-elementor-authenticated-contributor-arbitrary-file-read-via-path-traversal-in-repeater-jsoncsv-ur","Unlimited Elements For Elementor \u003C= 2.0.6 - Authenticated (Contributor+) Arbitrary File Read via Path Traversal in Repeater JSON\u002FCSV URL with Path Traversal","The Unlimited Elements for Elementor plugin for WordPress is vulnerable to Arbitrary File Read via the Repeater JSON\u002FCSV URL parameter in versions up to, and including, 2.0.6. This is due to insufficient path traversal sanitization in the URLtoRelative() and urlToPath() functions, combined with the ability to enable debug output in widget settings. The URLtoRelative() function only performs a simple string replacement to remove the site's base URL without sanitizing path traversal sequences (..\u002F), and the cleanPath() function only normalizes directory separators without removing traversal components. This allows an attacker to provide a URL like http:\u002F\u002Fsite.com\u002F..\u002F..\u002F..\u002F..\u002Fetc\u002Fpasswd which, after URLtoRelative() strips the domain, results in \u002F..\u002F..\u002F..\u002F..\u002Fetc\u002Fpasswd being concatenated with the base path and ultimately resolved to \u002Fetc\u002Fpasswd. This makes it possible for authenticated attackers with Author-level access and above to read arbitrary local files from the WordPress host, including sensitive files such as wp-config.","unlimited-elements-for-elementor",null,"\u003C=2.0.6","2.0.7","high",7.5,"CVSS:3.1\u002FAV:N\u002FAC:L\u002FPR:N\u002FUI:N\u002FS:U\u002FC:H\u002FI:N\u002FA:N","Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal')","2026-04-16 17:54:33","2026-04-24 14:07:17",[19],"https:\u002F\u002Fwww.wordfence.com\u002Fthreat-intel\u002Fvulnerabilities\u002Fid\u002F9e7e3763-4606-4fc4-aa0f-b67e6087bdc2?source=api-prod",8,[],"researched",false,3,"# Exploitation Research Plan: CVE-2026-4659 (Unlimited Elements For Elementor)\n\n## 1. Vulnerability Summary\nThe **Unlimited Elements For Elementor** plugin (\u003C= 2.0.6) contains an authenticated arbitrary file read vulnerability. The flaw exists in how the plugin converts a provided \"Repeater JSON\u002FCSV URL\" into a local file path. Specifically, the `URLtoRelative()` function removes the site's base URL via simple string replacement without sanitizing for path traversal (`..\u002F`) sequences. When this processed string is passed to `urlToPath()`, it is concatenated with the site's base path and resolved. An attacker can provide a URL pointing to the local site followed by traversal sequences (e.g., `https:\u002F\u002Fexample.com\u002F..\u002F..\u002F..\u002F..\u002Fetc\u002Fpasswd`) to read any file on the server that the PHP process has permission to access.\n\n## 2. Attack Vector Analysis\n*   **Endpoint:** Elementor Editor \u002F Post Save (via `_elementor_data` post meta) or the widget rendering engine.\n*   **Vulnerable Parameters:** Any widget field that utilizes the \"Repeater\" with \"Remote JSON\u002FCSV\" functionality. Specifically, the parameter used to store the remote URL.\n*   **Authentication:** Contributor-level access or higher is required to edit posts\u002Fpages and use Elementor widgets.\n*   **Preconditions:** \n    1.  The plugin \"Unlimited Elements\" must be active.\n    2.  The attacker must use or create a widget that utilizes a \"Repeater\" field with \"Remote Data\" enabled.\n    3.  The widget's debug mode or data display must be configured to output the fetched content (or the content must be rendered in the widget).\n\n## 3. Code Flow\n1.  **Entry Point:** A widget is rendered on the frontend or inside the Elementor editor.\n2.  **Data Fetching:** The widget checks if \"Remote JSON\u002FCSV\" is enabled.\n3.  **Path Resolution:**\n    *   The user-provided URL (e.g., `get_option('siteurl') . '\u002F..\u002F..\u002F..\u002F..\u002Fetc\u002Fpasswd'`) is passed to `URLtoRelative()`.\n    *   `URLtoRelative()` (inferred file: `provider\u002Fcore\u002Fframework\u002Fhelpers\u002Funite_functions.class.php`) performs: `str_replace(get_option('siteurl'), '', $url)`.\n    *   Result: `\u002F..\u002F..\u002F..\u002F..\u002Fetc\u002Fpasswd`.\n    *   `urlToPath()` takes this result and prepends `ABSPATH`.\n    *   `cleanPath()` normalizes slashes but does not remove `..\u002F`.\n4.  **File Sink:** The resolved path is passed to a file-reading function like `file_get_contents()` to retrieve the \"JSON\u002FCSV\" data.\n5.  **Output:** If the \"Debug\" option is enabled in the widget settings, or if the file content is mapped to a visible field in the repeater, the contents of the file are echoed to the page.\n\n## 4. Nonce Acquisition Strategy\nAccessing the Elementor editor as a Contributor requires standard WordPress authentication. Saving and rendering Elementor widgets requires the `elementor_ajax` nonce or the post-specific nonce.\n\n**Strategy:**\n1.  Log in as a Contributor.\n2.  Create a temporary post: `wp post create --post_type=post --post_status=publish --post_title=\"Exploit Page\"`.\n3.  Navigate to the Elementor editor for that post: `browser_navigate(\"\u002Fwp-admin\u002Fpost.php?post=ID&action=elementor\")`.\n4.  Extract the Elementor configuration nonces using `browser_eval`:\n    *   `browser_eval(\"window.elementorConfig.nonces.save_builder\")`\n5.  Unlimited Elements also localizes data. Check for:\n    *   `browser_eval(\"window.unite_admin_options?.nonce\")` (inferred localization key).\n\n## 5. Exploitation Strategy\nThe goal is to update a post's Elementor data to include a widget that attempts to read `\u002Fetc\u002Fpasswd`.\n\n1.  **Preparation:** Identify a widget slug from Unlimited Elements that supports repeaters (e.g., `uc_simple_list` or `uc_remote_json_tester`).\n2.  **Identify Meta Structure:** Elementor stores data in the `_elementor_data` post meta as a JSON string.\n3.  **Construct Payload:**\n    *   Create a JSON structure for an Elementor page containing one Unlimited Elements widget.\n    *   In the widget settings, set the remote URL parameter to: `[SITE_URL]\u002F..\u002F..\u002F..\u002F..\u002F..\u002F..\u002F..\u002F..\u002Fetc\u002Fpasswd`.\n    *   Set the \"use_remote_data\" flag to `true`.\n    *   Set the \"debug_mode\" or \"show_errors\" flag to `true` (if available).\n4.  **Update Post Meta:** Use the `http_request` tool to send a POST request to `admin-ajax.php` with the `elementor_ajax` action to save the builder data.\n    *   **Action:** `elementor_ajax`\n    *   **Actions Payload:** `{\"save_builder\":{\"action\":\"save_builder\",\"data\":{\"status\":\"publish\",\"elements\":[...MALICIOUS_JSON...]}}}`\n5.  **Trigger Read:** Navigate to the published post's URL. The rendering engine will execute the file read.\n6.  **Extract Data:** Scrape the response body for the contents of `\u002Fetc\u002Fpasswd`.\n\n## 6. Test Data Setup\n1.  **User:** Create a Contributor user.\n    *   `wp user create attacker attacker@example.com --role=contributor --user_pass=password`\n2.  **Plugin Config:** Ensure \"Unlimited Elements\" is active.\n3.  **Post:** Create a post to be edited.\n    *   `wp post create --post_type=post --post_status=publish --post_author=[USER_ID] --post_title=\"Traversal Test\"`\n4.  **Site URL:** Determine the site URL for the payload prefix.\n    *   `wp option get siteurl`\n\n## 7. Expected Results\n*   The `http_request` to `admin-ajax.php` returns `{\"success\":true}`.\n*   When navigating to the post frontend, the HTML contains the string `root:x:0:0:root:\u002Froot:\u002Fbin\u002Fbash` or the contents of `wp-config.php`.\n\n## 8. Verification Steps\n1.  **Meta Verification:** Check if the malicious URL was successfully saved.\n    *   `wp post meta get [POST_ID] _elementor_data`\n2.  **Log Check:** Check the WordPress debug log if the output isn't visible on the frontend.\n    *   `tail -f wp-content\u002Fdebug.log`\n3.  **File Content Verification:** Compare the exposed content with the actual file on the system (if in a controlled environment).\n\n## 9. Alternative Approaches\n*   **Direct Meta Update:** If the `elementor_ajax` request is too complex, use `wp post meta update [ID] _elementor_data '[JSON]'` via the shell to set up the state, then use the browser to simply view the result.\n*   **Different File:** If `\u002Fetc\u002Fpasswd` is restricted, attempt to read `wp-config.php` by calculating the depth from the `wp-content\u002Fplugins\u002Funlimited-elements-for-elementor\u002F` directory.\n    *   Payload: `[SITE_URL]\u002F..\u002F..\u002Fwp-config.php`\n*   **Shortcode Vector:** Some Unlimited Elements widgets can be triggered via shortcode. Attempt to inject the traversal via a shortcode attribute if the widget supports it: `[uc_widget_name remote_url=\"...\"]`.","The Unlimited Elements for Elementor plugin is vulnerable to authenticated arbitrary file read due to insufficient sanitization of the 'Repeater JSON\u002FCSV URL' parameter. An attacker with Contributor-level access or higher can use path traversal sequences (..\u002F) in a URL pointing to the local site, causing the plugin to resolve and read sensitive local files like wp-config.php and display their contents.","\u002F\u002F provider\u002Fcore\u002Fframework\u002Fhelpers\u002Funite_functions.class.php\n\npublic static function URLtoRelative($url) {\n    $siteUrl = get_option('siteurl');\n    \u002F\u002F Vulnerable: performs simple string replacement without checking for traversal sequences like '..\u002F'\n    $relative = str_replace($siteUrl, '', $url);\n    return $relative;\n}\n\n---\n\npublic static function urlToPath($url) {\n    $relative = self::URLtoRelative($url);\n    $path = ABSPATH . $relative;\n    return self::cleanPath($path);\n}\n\n---\n\npublic static function cleanPath($path) {\n    \u002F\u002F Vulnerable: only normalizes directory separators\n    $path = str_replace('\\\\', '\u002F', $path);\n    $path = str_replace('\u002F\u002F', '\u002F', $path);\n    return $path;\n}","--- provider\u002Fcore\u002Fframework\u002Fhelpers\u002Funite_functions.class.php\n+++ provider\u002Fcore\u002Fframework\u002Fhelpers\u002Funite_functions.class.php\n@@ -10,6 +10,7 @@\n \tpublic static function URLtoRelative($url) {\n \t\t$siteUrl = get_option('siteurl');\n \t\t$relative = str_replace($siteUrl, '', $url);\n+\t\t$relative = str_replace('..', '', $relative);\n \t\treturn $relative;\n \t}\n \n@@ -20,6 +21,11 @@\n \t\t$path = ABSPATH . $relative;\n-\t\treturn self::cleanPath($path);\n+\t\t$path = self::cleanPath($path);\n+\t\tif (strpos($path, ABSPATH) !== 0) {\n+\t\t\treturn null;\n+\t\t}\n+\t\treturn $path;\n \t}","1. Authenticate to the WordPress site as a Contributor or higher.\n2. Create a new post and open it in the Elementor editor.\n3. Add an Unlimited Elements widget that supports the 'Repeater' functionality with 'Remote Data' enabled (e.g., Simple List).\n4. Locate the configuration field for 'Repeater JSON\u002FCSV URL'.\n5. Set the URL value to the site's base URL followed by path traversal sequences and the target file path (e.g., http:\u002F\u002Fexample.com\u002F..\u002F..\u002F..\u002F..\u002Fwp-config.php).\n6. Enable 'Debug Mode' or 'Show Errors' within the widget settings to ensure the fetched content is output to the browser.\n7. Save the post or trigger a preview; the plugin will strip the base URL, concatenate the traversal string with the absolute path, and read\u002Fdisplay the contents of the target file via the widget's render output.","gemini-3-flash-preview","2026-04-20 20:17:15","2026-04-20 20:17:41",{"type":34,"vulnerable_version":35,"fixed_version":9,"vulnerable_browse":36,"vulnerable_zip":37,"fixed_browse":9,"fixed_zip":9,"all_tags":38},"plugin","1.5.132","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Funlimited-elements-for-elementor\u002Ftags\u002F1.5.132","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Funlimited-elements-for-elementor.1.5.132.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Funlimited-elements-for-elementor\u002Ftags"]