Widget Options – Advanced Conditional Visibility for Gutenberg Blocks & Classic Widgets <= 4.1.3 - Authenticated (Contributor+) Remote Code Execution
Description
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.1.3. This makes it possible for authenticated attackers, with Contributor-level access and above, to execute code on the server.
CVSS Vector Breakdown
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:HTechnical Details
<=4.1.3What Changed in the Fix
Changes introduced in v4.2.0
Source Code
WordPress.org SVNThis research plan outlines the steps to exploit **CVE-2026-27984**, an Authenticated (Contributor+) Remote Code Execution vulnerability in the **Widget Options** plugin. ### 1. Vulnerability Summary The "Widget Options" plugin provides a "Display Logic" module that allows users to control the visi…
Show full research plan
This research plan outlines the steps to exploit CVE-2026-27984, an Authenticated (Contributor+) Remote Code Execution vulnerability in the Widget Options plugin.
1. Vulnerability Summary
The "Widget Options" plugin provides a "Display Logic" module that allows users to control the visibility of Gutenberg blocks and widgets using PHP conditional tags. The plugin takes user-provided PHP code and executes it using eval(). While intended for administrators, the plugin fails to properly restrict access to this functionality in Gutenberg block settings, allowing any user with post-editing privileges (Contributor and above) to inject and execute arbitrary PHP code.
2. Attack Vector Analysis
- Endpoint: WordPress REST API (
/wp-json/wp/v2/posts) or the Plugin's AJAX handler (/wp-admin/admin-ajax.php). - Vulnerable Parameter:
logicattribute within thewidgetopts_visibilityblock attribute (orwidgetopts_logic). - Authentication: Contributor-level session required.
- Preconditions: The "Display Logic" module must be active. If not active, it can potentially be enabled by a Contributor via the vulnerable AJAX handler if capability checks are missing.
3. Code Flow
- Entry Point (Gutenberg): A Contributor edits a post and adds/modifies a block. The visibility settings are stored in the block's attributes (e.g.,
widgetopts_visibility). - Persistence: When the post is saved, the attributes are stored in the
post_content(block comments) or as post metadata. - Execution Sink: When the post is rendered on the frontend (via
render_blockorthe_contenthooks), the plugin's visibility engine parses the block attributes. - The Sink: The plugin calls a logic-checking function (referenced in
includes/admin/settings/modules/logic.phpas being "EVAL'd directly"). This function takes the string from thelogicfield and passes it toeval().
4. Nonce Acquisition Strategy
The exploit requires two nonces: one for the WordPress REST API and one for the plugin's custom AJAX actions.
- REST API Nonce: Required to update/create posts.
- Variable:
window.wpApiSettings.nonce
- Variable:
- Widget Options AJAX Nonce: Required for interacting with the plugin's settings (e.g., ensuring the Logic module is active).
- Localization Key:
widgetopts(fromassets/js/settings.js) - Nonce Key:
ajax_nonce
- Localization Key:
Action Plan:
- Navigate to the post editor: `browser_navigate("/wp-admin/post-new
Summary
The Widget Options plugin for WordPress is vulnerable to Remote Code Execution via its Display Logic feature, which uses the PHP eval() function to process visibility rules. While intended for administrators, the plugin allows users with Contributor-level access and above to define these rules for Gutenberg blocks, leading to arbitrary code execution when the blocks are rendered on the site.
Vulnerable Code
/* includes/admin/settings/modules/logic.php lines 48-50 */ <p> <?php _e( "<strong>Please note</strong> that the display logic you introduce is EVAL'd directly. Anyone who has access to edit widget appearance will have the right to add any code, including malicious and possibly destructive functions. There is an optional filter <code>widget_options_logic_override</code> which you can use to bypass the EVAL with your own code if needed.", 'widget-options' )?> </p>
Security Fix
@@ -4,7 +4,61 @@ _init: function() { $('select.widgetopts-select2').each(function() { - $(this).select2({ + var $el = $(this); + + // Use AJAX mode for snippet dropdown + if ($el.attr('name') === 'widgetopts_logic_snippet_id') { + $el.select2({ + width: '100%', + allowClear: true, + placeholder: '— No Logic (Always Show) —', + minimumInputLength: 0, + ajax: { + url: ajaxurl, + type: 'POST', + dataType: 'json', + delay: 250, + data: function(params) { + return { + action: 'widgetopts_get_snippets_ajax', + search: params.term || '' + }; + }, + processResults: function(response) { + var results = [{id: '', text: '— No Logic (Always Show) —'}]; + if (response.success && response.data && response.data.snippets) { + response.data.snippets.forEach(function(snippet) { + results.push({id: String(snippet.id), text: snippet.title, description: snippet.description || ''}); + }); + } + return { results: results }; + }, + cache: true + } + }).on('change', $.proxy(WidgetOptsSelect2._maybePreview, this.context));
Exploit Outline
1. Login to WordPress with Contributor-level credentials or higher. 2. Open the Gutenberg block editor (e.g., create a new post). 3. Add any block and modify its attributes via the REST API or editor interface to include visibility logic. Specifically, the 'widgetopts_visibility' block attribute (or the corresponding 'logic' field in the editor's block settings) should be populated with arbitrary PHP code (e.g., '<?php system("whoami"); ?>' or 'return true; eval("...");'). 4. Save or update the post. The malicious PHP code is now stored in the post content as part of the block's metadata. 5. View the post on the site's frontend or through the preview functionality. 6. During the rendering process, the plugin retrieves the 'logic' string from the block attributes and passes it to the PHP eval() function, executing the attacker's payload on the server.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.