This is a chainsaw locked in the janitor closet, not a bomb tossed through the front door
CVE-2026-7252 is an arbitrary file deletion flaw in the WP-Optimize WordPress plugin caused by weak path validation in unscheduled_original_file_deletion and the use of a public attachment meta key, original-file. Affected versions are all releases up to and including 4.5.2; the vendor fix landed in 4.5.3. An attacker who already has Author-level access or higher can point that meta key at a server file and trigger deletion, including high-value targets like wp-config.php.
The vendor's 8.1/HIGH score is technically defensible, but operationally it overstates the population at risk. This is not unauthenticated internet RCE; it is a post-initial-access WordPress role abuse issue that needs a valid session plus a role many public sites never grant to strangers. The impact can absolutely be ugly, but the entry condition is the whole story here, so this gets downgraded to MEDIUM for enterprise patch scheduling.
4 steps from start to impact.
Land an Author session with browser or Burp Suite
- Target runs WP-Optimize <= 4.5.2
- Attacker has valid WordPress credentials
- Compromised account has Author-level privileges or higher
- Many enterprise WordPress sites do not expose public self-registration for Author roles
- SSO, MFA, and role reviews frequently reduce reachable accounts
- This already assumes some prior foothold against the CMS identity plane
Write a malicious original-file value via WordPress Media UI or wp-json/wp/v2/media
original-file is a non-protected attachment meta key, an Author can create or modify it on media they control. The attacker uploads or selects an attachment, then sets the meta value to an arbitrary server path such as the absolute path to wp-config.php. This uses normal WordPress functionality, so the traffic can look like ordinary media management.- Attacker can create or edit an attachment they own
- REST API or media editing path is reachable
- Server file path is knowable or guessable
- The attacker may need path knowledge for high-value targets
- Hardened sites may restrict REST API access for non-admin roles
- Some content workflows limit who can upload media at all
original-file. Most generic VA tooling has weak coverage here.Trigger unscheduled_original_file_deletion through WP-Optimize image workflow
- WP-Optimize image/smush functionality is present and callable
- The chosen file is writable by the web server account
- The deletion workflow can be triggered by the attacker's role
- Filesystem permissions may block deletion of some targets
- Operational settings around image retention can change whether the workflow is reachable
- Some hosting stacks isolate writable paths tightly enough to reduce blast radius
wp-config.php, is the practical control. EDR on the host may also catch php-fpm/webserver child processes unlinking sensitive files.Convert deletion into outage or takeover with the WordPress installer
wp-config.php can force WordPress into reinstall state, which turns a file deletion into either immediate availability loss or full site takeover if the attacker can drive the reconfiguration flow. In weaker deployments, that can cascade to remote code execution or complete content/database compromise. In stronger deployments, it still produces a very real outage.- A high-value file such as
wp-config.phpis successfully deleted - The site lacks controls preventing malicious reinstall/rebinding
- Attackers can reach the installer flow before defenders restore the file
- This is not guaranteed one-shot RCE; it depends on target file choice and site state
- Fast backup restore or immutable config management can stop the chain at disruption
- Some environments protect config outside the standard WordPress webroot path
wp-config.php, sudden transition to installer pages, and abnormal file restore events. Synthetic monitoring can catch the outage side quickly even if security tools do not.The supporting signals.
| In-the-wild status | No public exploitation evidence found in reviewed sources and not listed in CISA KEV as of 2026-05-29. That matters more than the raw file-deletion impact when you're triaging 10,000 hosts. |
|---|---|
| Proof-of-concept availability | No public PoC located in reviewed sources. That said, the exploit path is straightforward for anyone who already has an Author session, so lack of a GitHub repo is not strong protection. |
| EPSS | 0.00246 (~0.246%) from the user-provided intel, which aligns with roughly mid-pack percentile territory in public feeds rather than a breakout exploitation signal. |
| KEV status | Not KEV-listed as of 2026-05-29. No CISA due date pressure, no active-exploitation override. |
| CVSS vector readout | CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:H means easy network reachability once authenticated, no user interaction, and heavy integrity/availability impact. The PR:L is the key downward pressure. |
| Affected versions | WP-Optimize <= 4.5.2. |
| Fixed version | 4.5.3. WordPress.org changelog for 2026-04-29 explicitly says: security fix for a path traversal risk. |
| Exposure population | The plugin shows 1+ million active installations on WordPress.org, so the software is widespread. But there is no clean internet-wide fingerprint for this specific vulnerable plugin/version, and exploitability still depends on WordPress role exposure. |
| Disclosure timeline | Publicly disclosed 2026-05-07; Wordfence lists the vulnerability as published 2026-05-06 and updated 2026-05-07. |
| Reporter | Reported by lhking via Wordfence according to the vendor-adjacent vulnerability record. |
noisgate verdict.
The single biggest reason this lands in MEDIUM is the Author-level authentication requirement: this is a post-initial-access content-platform abuse bug, not a front-door internet compromise. The impact is real, but the reachable population collapses sharply once you require a valid CMS session plus a specific role and then a successful follow-on path to destructive file deletion or takeover.
Why this verdict
- Requires Author credentials:
PR:Lis not a paperwork detail here; it means the attacker already beat your identity layer or another WordPress bug first. - RCE is conditional, not native: the vulnerability is arbitrary file deletion, and the takeover story depends on deleting the right file and successfully converting that into reinstall-state abuse or equivalent follow-on impact.
- Exposure is broad but not broadly reachable: WP-Optimize has 1M+ installs, but most enterprise sites are not handing anonymous users Author rights, which meaningfully narrows the practical target set.
Why not higher?
This is not an unauthenticated edge-service flaw and not a reliable one-packet RCE. The exploit chain depends on authenticated WordPress role abuse and then a second-stage conversion from file deletion to full compromise, which is enough friction to keep it out of HIGH/CRITICAL in enterprise prioritization.
Why not lower?
Once the attacker has the needed role, exploitation is simple and impact can be severe: deleting wp-config.php can produce immediate outage and sometimes full site takeover. On content-heavy organizations with many contributor/editorial accounts, the prerequisite is not exotic, so this is more than backlog lint.
What to do — in priority order.
- Prune Author accounts — Review every WordPress site using WP-Optimize and remove stale or unnecessary Author+ accounts, especially on public-facing marketing properties and microsites. For a MEDIUM verdict there is no noisgate mitigation SLA, but this is the best temporary risk reduction if patch rollout will stretch.
- Restrict media and REST access for low-trust roles — If your publishing workflow allows it, limit media upload/edit and attachment REST operations for non-admin roles until all sites are on 4.5.3+. This directly attacks the exploit path by preventing untrusted users from setting the attacker-controlled attachment metadata.
- Monitor
wp-config.phpand core files — Add file integrity monitoring or host telemetry for deletion/modification ofwp-config.php,.htaccess, and WordPress core files under the webroot. There is no mitigation SLA for MEDIUM, but this gives you a fast tripwire for the exact destructive outcome this bug is known for. - Put editorial sites behind SSO and MFA — Where business reality allows it, move WordPress author/editor authentication behind your enterprise IdP and require MFA for all content roles, not just admins. That cuts off the most realistic entry condition for this bug: compromised low-privilege publishing accounts.
WAF-onlythinking doesn't save you here, because the attacker can abuse legitimate authenticated WordPress UI and REST flows rather than an obvious malicious payload.Admin MFA onlyis insufficient, because Author access is enough for exploitation according to the vulnerability record.Unauthenticated external scanninggives false comfort, because this flaw sits behind login and role checks; many scanners will report nothing while the site is still vulnerable.
Crowdsourced verification payload.
Run this on the target WordPress host or against a mounted webroot from an auditor workstation. Invoke it as python3 check_wp_optimize_cve_2026_7252.py /var/www/html or python check_wp_optimize_cve_2026_7252.py C:\inetpub\wwwroot; it only needs read access to the plugin files.
#!/usr/bin/env python3
# check_wp_optimize_cve_2026_7252.py
# Exit codes: 0=PATCHED, 1=VULNERABLE, 2=UNKNOWN
import os
import re
import sys
from pathlib import Path
VULN_MAX = "4.5.2"
PATCHED_MIN = "4.5.3"
def normalize(v):
parts = re.findall(r"\d+", v or "")
if not parts:
return None
return tuple(int(x) for x in parts)
def cmp_ver(a, b):
na = normalize(a)
nb = normalize(b)
if na is None or nb is None:
return None
maxlen = max(len(na), len(nb))
na = na + (0,) * (maxlen - len(na))
nb = nb + (0,) * (maxlen - len(nb))
if na < nb:
return -1
if na > nb:
return 1
return 0
def extract_version(text):
patterns = [
r"(?im)^\s*Stable tag:\s*([0-9][0-9A-Za-z._-]*)\s*$",
r"(?im)^\s*Version:\s*([0-9][0-9A-Za-z._-]*)\s*$",
r"(?im)^\s*\*\s*Version\s+([0-9][0-9A-Za-z._-]*)\s*$",
]
for pat in patterns:
m = re.search(pat, text)
if m:
return m.group(1).strip()
return None
def read_text(path):
try:
return Path(path).read_text(encoding="utf-8", errors="ignore")
except Exception:
return None
def locate_plugin(root):
root = Path(root)
candidates = [
root / "wp-content" / "plugins" / "wp-optimize",
root / "wordpress" / "wp-content" / "plugins" / "wp-optimize",
]
for c in candidates:
if c.is_dir():
return c
for p in root.rglob("wp-optimize"):
if p.is_dir() and p.parent.name == "plugins":
return p
return None
def main():
if len(sys.argv) != 2:
print("UNKNOWN - usage: python3 check_wp_optimize_cve_2026_7252.py <wordpress_root>")
sys.exit(2)
root = sys.argv[1]
plugin_dir = locate_plugin(root)
if not plugin_dir:
print("UNKNOWN - WP-Optimize plugin directory not found")
sys.exit(2)
files_to_check = [
plugin_dir / "readme.txt",
plugin_dir / "wp-optimize.php",
]
version = None
source_file = None
for f in files_to_check:
if f.is_file():
txt = read_text(f)
if txt:
version = extract_version(txt)
if version:
source_file = str(f)
break
if not version:
print(f"UNKNOWN - unable to determine WP-Optimize version from {plugin_dir}")
sys.exit(2)
if cmp_ver(version, VULN_MAX) is not None and cmp_ver(version, VULN_MAX) <= 0:
print(f"VULNERABLE - WP-Optimize version {version} detected in {source_file} (affected: <= {VULN_MAX})")
sys.exit(1)
if cmp_ver(version, PATCHED_MIN) is not None and cmp_ver(version, PATCHED_MIN) >= 0:
print(f"PATCHED - WP-Optimize version {version} detected in {source_file} (fixed: >= {PATCHED_MIN})")
sys.exit(0)
print(f"UNKNOWN - WP-Optimize version {version} detected in {source_file}, but comparison failed")
sys.exit(2)
if __name__ == "__main__":
main()
If you remember one thing.
Sources
What defenders are saying.
Crowdsourced verification outputs.
Results submitted by users who ran the verification payload against their environment.