CVE-2026-104751: Rank Math SEO Unauthenticated SEO Analyzer Results Deletion
Source-level analysis and local runtime validation of unauthenticated SEO Analyzer cache deletion in Rank Math SEO versions before 1.0.280.
CVE-2026-104751: Rank Math SEO Unauthenticated SEO Analyzer Results Deletion
Overview
CVE-2026-104751 is a missing authorization vulnerability in the Rank Math SEO WordPress plugin. In versions before 1.0.280, the SEO Analyzer could delete its stored analysis results and last-run timestamp as a side effect of module initialization, without authentication, capability validation, or a nonce check.
I validated the behavior on Rank Math SEO 1.0.279 in an isolated WordPress lab. An unauthenticated request reached the storage-clearing branch; the server responded with a Rank Math redirect, and two previously populated WordPress options disappeared. Negative controls showed no deletion when the triggering parameter was absent or different.
The data at issue is regenerable SEO Analyzer output, not posts, credentials, site configuration, or backup archives. No information disclosure, account compromise, remote code execution, or site-wide denial of service was demonstrated.
Summary
| Property | Value |
|---|---|
| CVE | CVE-2026-104751 |
| Product | Rank Math SEO (seo-by-rank-math) |
| Affected versions (WPScan) | < 1.0.280 |
| Validated version | 1.0.279 |
| Fixed version (WPScan) | 1.0.280 |
| Weakness | CWE-862 — Missing Authorization |
| Classification | No Authorisation / Broken Access Control |
| Severity | Medium |
| CVSS v3.1 | 5.3 (CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:N) |
| Authentication required | None |
| Researcher and submitter | Duy Tran (MrDarkRoot) |
| WPVDB ID | b68d607d-aad8-46ad-a522-5eaeea738d8c |
| Public disclosure (WPScan) | October 12, 2026 |
Expected Behavior
Only an authorized administrator should be able to clear stored SEO Analyzer results. A destructive operation should validate the user’s relevant capability and the authenticity of the action before mutating WordPress options. Unauthenticated AJAX initialization should not grant permission to delete administrator-generated analysis state.
Actual Behavior
The SEO Analyzer constructor invokes maybe_clear_storage(). In the vulnerable implementation, this method checks a request parameter and immediately deletes stored SEO results and their timestamp, with no capability or nonce verification before the destructive calls.
1. Untrusted parameter controls the deletion sink
The relevant code from includes/modules/seo-analysis/class-seo-analyzer.php in the examined release:
1
2
3
4
5
6
7
8
private function maybe_clear_storage() {
if ( '1' === Param::request( 'clear_results' ) ) {
delete_option( 'rank_math_seo_analysis_results' );
delete_option( 'rank_math_seo_analysis_date' );
Helper::redirect( Security::remove_query_arg_raw( 'clear_results' ) );
exit;
}
}
The value of clear_results is attacker-controlled. There is no current_user_can() or nonce check before delete_option(). The redirect is a consequence of the branch, not an authorization defense.
2. The deletion runs during construction
1
2
3
4
5
6
7
8
public function __construct() {
$this->analyse_url = home_url();
$this->action( 'init', 'set_url' );
$this->maybe_clear_storage();
$this->ajax( 'analyze', 'analyze_me' );
$this->ajax( 'enable_auto_update', 'enable_auto_update' );
}
This places request-driven database mutation in object initialization, rather than in a dedicated privileged action handler.
3. Unauthenticated AJAX requests instantiate the analyzer
In includes/modules/seo-analysis/class-admin.php, the module constructs the analyzer when the AJAX execution flag is set or its administration page is current:
1
2
3
4
if ( ( defined( 'DOING_AJAX' ) && DOING_AJAX ) || $this->page->is_current_page() ) {
include_once 'seo-analysis-tests.php';
$this->analyzer = new SEO_Analyzer();
}
WordPress’s wp-admin/admin-ajax.php defines the AJAX/admin context before loading WordPress. The Rank Math module-loading path treated that context as sufficient to instantiate the SEO Analysis administration component, even when the visitor was logged out.
Thus, a request could reach the constructor and maybe_clear_storage() before any user-level authorization check.
4. Regeneration has an authorization boundary
By contrast, the analyzer’s analyze_me() action includes:
1
2
check_ajax_referer( 'rank-math-ajax-nonce', 'security' );
$this->has_cap_ajax( 'site_analysis' );
Generating the results was nonce- and capability-gated, but deleting the same results was not. This asymmetric design is the core trust-boundary failure.
Required Conditions / Attack Preconditions
The SEO Analysis module must be active (enabled by default in the examined installation), and results must already have been generated for there to be any data to remove. An attacker does not require WordPress credentials, cookies, API tokens, or special headers.
Trust-Boundary Analysis
The violated invariant was:
1
2
External HTTP input
must not authorize destructive administrative state changes
The vulnerable flow was:
1
2
3
4
5
Unauthenticated admin-ajax bootstrap
-> Rank Math administrative module initialization
-> new SEO_Analyzer()
-> maybe_clear_storage()
-> delete_option() twice
is_admin() and DOING_AJAX describe WordPress execution context; neither proves an authenticated or authorized administrator.
Technical Validation
The original report documented an isolated environment:
| Component | Tested version |
|---|---|
| WordPress | 7.1.2 (reported lab configuration) |
| Rank Math SEO | 1.0.279 |
| PHP | 8.2.34 |
| MySQL | 8.0.46 |
| Authentication | None |
Baseline
The options table contained:
1
2
rank_math_seo_analysis_results 10290 bytes
rank_math_seo_analysis_date 10 bytes
Positive result
After an unauthenticated trigger request, the application returned:
1
2
3
HTTP/1.1 302 Found
X-Redirect-By: Rank Math
Location: /wp-admin/admin-ajax.php
Database inspection then showed neither option existed. The two options were still absent when checked 30 seconds later. The redirect alone would not prove deletion; the before-and-after database inspection did.
Negative controls
Requests to the same AJAX entry point with the triggering parameter absent or set to a non-triggering value returned HTTP 400. In these controls, both options remained present and unchanged.
The differential behavior connects the deletion to the specific unprotected branch rather than ordinary AJAX bootstrap.
Proof of Concept
A single unauthenticated GET request was sufficient to trigger the deletion in the local lab. The original report preserved the precise request and database checks.
This public post intentionally focuses on the verified code path and observed effects; it does not reproduce the complete operational trigger request. The issue is publicly disclosed and patched in 1.0.280 according to WPScan.
Impact
Observed: An unauthenticated actor deleted the stored SEO analysis results and date. The change persisted until an authorized administrator regenerated the analysis.
Potential: Repeated requests could continually clear regenerated audit state, disrupting the usefulness of retained SEO Analyzer results.
Limits: These options are regenerable analysis data. The test did not establish broader WordPress content deletion, privilege escalation, information disclosure, remote code execution, or general service unavailability. WPScan assigns a 5.3 Medium CVSS score.
Remediation
WPScan lists the issue as fixed in Rank Math SEO 1.0.280. Administrators should update to version 1.0.280 or newer.
Secure implementation principles include:
- Check the
rank_math_site_analysiscapability and verify a nonce before any storage deletion. - Move destructive logic from constructors to explicit, authorized action handlers.
- Do not confuse an AJAX/admin execution context with an authenticated administrator.
- Regression-test the missing, non-triggering, and unauthenticated request cases against the stored options.
Disclosure Timeline
| Date | Event |
|---|---|
| Date not publicly specified | Local source review and runtime validation on 1.0.279 |
| October 12, 2026 | Public WPScan disclosure of CVE-2026-104751 |
| October 13, 2026 | Technical write-up updated with confirmed CVE, version range, severity and patch metadata |
Research Credit
Original researcher and submitter: Duy Tran (MrDarkRoot).
WPScan identifies the finding as verified. The source-level analysis and lab results here are based on my original report; advisory metadata such as affected versions, CVE identifier, fixed version and CVSS score comes from the public WPScan record.
References
- WPScan / WPVDB — Rank Math SEO unauthenticated SEO Analyzer results deletion
- CVE-2026-104751
- NVD — CVE-2026-104751
- Rank Math SEO on WordPress.org
- Rank Math SEO 1.0.279 source, SEO Analyzer
Responsible Disclosure Notice
This research was conducted in an isolated local test environment and published following public advisory disclosure. Do not test third-party websites without authorization. Update Rank Math SEO to 1.0.280 or later to address the reported issue.