WP 404 Auto Redirect <= 1.0.5 - Authenticated (Admin+) Stored Cross-Site Scripting
Description
The WP 404 Auto Redirect to Similar Post plugin for WordPress is vulnerable to Stored Cross-Site Scripting via admin settings in all versions up to, and including, 1.0.5 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.0.5What Changed in the Fix
Changes introduced in v1.0.6
Source Code
WordPress.org SVN# Exploitation Research Plan - CVE-2025-12037 ## 1. Vulnerability Summary The **WP 404 Auto Redirect to Similar Post** plugin (<= 1.0.5) is vulnerable to **Stored Cross-Site Scripting (XSS)** via its administrative settings. The vulnerability exists because the plugin registers a settings group but…
Show full research plan
Exploitation Research Plan - CVE-2025-12037
1. Vulnerability Summary
The WP 404 Auto Redirect to Similar Post plugin (<= 1.0.5) is vulnerable to Stored Cross-Site Scripting (XSS) via its administrative settings. The vulnerability exists because the plugin registers a settings group but fails to adequately sanitize the input in its sanitize_callback and fails to escape the stored values when rendering them on the admin settings page. Specifically, the sanitize_setting function in includes/admin.php only validates the fallback['url'] field, leaving all other settings fields (such as exclusion rules) vulnerable to injection. This allows an authenticated administrator to inject arbitrary scripts that execute when any administrator views the plugin's settings page, especially in environments where unfiltered_html is disabled (like WordPress Multi-site).
2. Attack Vector Analysis
- Endpoint:
/wp-admin/options.php(The standard WordPress Settings API handler). - Vulnerable Parameter:
wp404arsp_settings[rules][exclude][post_meta](or other keys within thewp404arsp_settingsarray). - Authentication Level: Administrator (High privilege).
- Precondition: The site must have
unfiltered_htmldisabled (standard on Multi-site or viaDISALLOW_UNFILTERED_HTMLinwp-config.php) for this to be considered a vulnerability rather than a feature. - Payload:
"><script>alert(window.origin)</script>
3. Code Flow
- Registration: In
includes/admin.php, the functionadmin_settings()(hooked toadmin_init) callsregister_setting('wp404arsp_settings', 'wp404arsp_settings', ...)withsanitize_callbackset tosanitize_setting. - Weak Sanitization: The
sanitize_setting($settings)function inincludes/admin.phponly performs:
All other nested keys in the$settings['fallback']['url'] = sanitize_url($settings['fallback']['url']); return $settings;$settingsarray (likerules,exclude,post_meta) are returned to the database without any filtering. - Retrieval: When an admin visits the settings page,
admin_page()callswp404arsp_settings_get()(defined inclass/class-settings.php). - Unescaped Output: The
WP_404_Auto_Redirect_Settings::get()function retrieves the option and only escapes the fallback URL usingesc_url. Other fields remain raw. - Sink: While the truncation in
admin.phpobscures the exact HTML for thepost_metafield, it follows the pattern of thedebugcheckbox. The values are echoed into HTML attributes of inputs (likely text inputs for "Exclude Meta") without usingesc_attr().
4. Nonce Acquisition Strategy
The vulnerability is in the WordPress Settings API. To exploit it, a valid _wpnonce for the wp404arsp_settings-options action is required.
- Navigate: Use
browser_navigateto reach the plugin settings page:/wp-admin/options-general.php?page=wp-404-auto-redirect. - Extract: Since the page uses
settings_fields('wp404arsp_settings'), a hidden field named_wpnonceis generated within the settings form. - Command:
This retrieves the nonce directly from the DOM in the correct session context.browser_eval("document.querySelector('input[name=\"_wpnonce\"]').value")
5. Exploitation Strategy
Step 1: Authentication and Setup
- Log in to the WordPress instance as an administrator.
- (Optional but recommended for PoC) Ensure
define('DISALLOW_UNFILTERED_HTML', true);is set inwp-config.php.
Step 2: Nonce Retrieval
- Navigate to the settings page:
/wp-admin/options-general.php?page=wp-404-auto-redirect. - Use
browser_evalto extract the_wpnoncevalue.
Step 3: Injection Request
- Send a POST request to
/wp-admin/options.phpusing thehttp_requesttool. - Headers:
Content-Type: application/x-www-form-urlencoded - Body:
(Note: Include other default settings to ensure the array structure remains valid).option_page=wp404arsp_settings &action=update &_wpnonce=[EXTRACTED_NONCE] &wp404arsp_settings[rules][exclude][post_meta]=%22%3E%3Cscript%3Ealert%28window.origin%29%3C%2Fscript%3E &wp404arsp_settings[priority]=999 &wp404arsp_settings[method]=301
Step 4: Trigger XSS
- Navigate back to
/wp-admin/options-general.php?page=wp-404-auto-redirect. - Observe the script execution (the
alertwill trigger).
6. Test Data Setup
- Plugin Installation: Install and activate
wp-404-auto-redirect-to-similar-postversion 1.0.5. - User: Create or use an existing Administrator account.
- Environment: If testing on a standard single-site install, add
define( 'DISALLOW_UNFILTERED_HTML', true );towp-config.phpto simulate the restricted environment where the vulnerability is most relevant.
7. Expected Results
- The POST request to
options.phpshould return a302 Foundredirect back to the settings page with asettings-updated=trueparameter. - The
wp404arsp_settingsoption in thewp_optionstable will now contain the raw HTML payload in the[rules][exclude][post_meta]key. - Upon loading the settings page, the browser will execute the injected
<script>because the value is echoed inside an input attribute likevalue="..."withoutesc_attr(), allowing the payload to break out of the attribute.
8. Verification Steps
- WP-CLI Verification:
Verify that thewp option get wp404arsp_settings --format=jsonrules -> exclude -> post_metavalue contains the raw<script>tag. - DOM Verification: Inspect the HTML source of the settings page and look for the injected string:
<input ... value=""><script>alert(window.origin)</script>" ...>
9. Alternative Approaches
- Payload Variance: If
post_metais not easily accessible in the UI, try injecting intowp404arsp_settings[rules][exclude][term_meta]orwp404arsp_settings[priority]. Even ifpriorityis cast to an integer during its use intemplate_redirect, it may be rendered as a string in the admin form. - Tab Selection: The plugin uses a tabbed interface. The payload might be hidden in the "Post Types" or "Taxonomies" tab. Use
browser_eval("jQuery('a[href=\"#settings\"]').click()")or similar to ensure the correct tab is visible if the browser doesn't execute the script immediately.
Summary
The WP 404 Auto Redirect to Similar Post plugin for WordPress is vulnerable to Stored Cross-Site Scripting via its administrative settings in versions up to 1.0.5. This occurs because the plugin fails to sanitize all keys in the settings array upon saving and fails to escape them when rendering the settings page, allowing administrators to inject malicious scripts.
Vulnerable Code
/* File: includes/admin.php (~line 64) */ function sanitize_setting($settings){ $settings['fallback']['url'] = sanitize_url($settings['fallback']['url']); return $settings; } --- /* File: class/class-settings.php (~line 79) */ // Esc Fallback $settings['fallback']['url'] = esc_url($settings['fallback']['url']); // Headers if(((int)$settings['method'] != 301) && ((int)$settings['method'] != 302)){ $settings['method'] = 301; } // Return return $settings;
Security Fix
@@ -79,6 +79,9 @@ // Esc Fallback $settings['fallback']['url'] = esc_url($settings['fallback']['url']); + // Esc Priority + $settings['priority'] = (int) $settings['priority']; + // Headers if(((int)$settings['method'] != 301) && ((int)$settings['method'] != 302)){ $settings['method'] = 301; @@ -64,6 +64,7 @@ function sanitize_setting($settings){ $settings['fallback']['url'] = sanitize_url($settings['fallback']['url']); + $settings['priority'] = (int) $settings['priority']; return $settings;
Exploit Outline
The exploit targets the WordPress Settings API by submitting a malicious payload into the plugin's configuration. An authenticated administrator first retrieves a valid CSRF nonce from the plugin's settings page at /wp-admin/options-general.php?page=wp-404-auto-redirect. They then send a POST request to /wp-admin/options.php including the nonce and the payload inside the wp404arsp_settings[rules][exclude][post_meta] or wp404arsp_settings[priority] parameters. The payload, such as a script tag designed to break out of an HTML attribute, is stored in the database. The XSS triggers whenever an administrator subsequently visits the plugin settings page, as the stored value is rendered without proper attribute escaping.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.