CVE Tools
Back to blog

CVE-2025-12057: the WordPress audio plugin that hands attackers your whole server

An unauthenticated arbitrary-upload → RCE in WavePlayer < 3.8.0 (CVSS 9.8) — mass-exploited in WP-SHELLSTORM despite a low EPSS and no KEV listing

CVE-2025-12057: the WordPress audio plugin that hands attackers your whole server. An unauthenticated arbitrary-upload → RCE in WavePlayer < 3.8.0 (CVSS 9.8) — mass-exploited in WP-SHELLSTORM desp
CVE-2025-12057: the WordPress audio plugin that hands attackers your whole server. An unauthenticated arbitrary-upload → RCE in WavePlayer < 3.8.0 (CVSS 9.8) — mass-exploited in WP-SHELLSTORM desp

A music widget is not the first place most teams look for a critical flaw. But WavePlayer — a popular commercial WordPress/WooCommerce audio player — shipped an unauthenticated arbitrary file upload in every version before 3.8.0, and the shortest path from that bug to a live webshell is about two HTTP requests. No login, no user interaction, full server compromise. Below: exactly how the chain works, why the usual "is it urgent?" signals under-called it, and what to do today.

What the flaw actually is

WavePlayer exposes an AJAX action called create_local_copy through its own query-string dispatcher (?wvpl-ajax=create_local_copy). Two mistakes stack on top of each other. First, the action performs no authorization check — an anonymous request reaches it. Second, it takes a url parameter naming a remote file, fetches it, and copies it locally with no validation of type, extension, or path. That's the classic CWE-434 (unrestricted file upload) shape, and here it lands in a web-served directory, so the write becomes execution (WPScan, NVD).

The exploitation chain

Put together, the attack is short and mechanical — which is exactly why mass scanners love it. Grab a nonce, POST the create_local_copy action with a url pointing at an attacker-hosted PHP payload, and the plugin writes that payload to a predictable path under wp-content/uploads/peaks/external/. Request the dropped file directly and the PHP runs. The flow below traces the whole thing, with the two chokepoints where defenders can break it.

CVE-2025-12057 exploitation chain

  1. Internet-facing WP with WavePlayer &lt; 3.8.0 — An anonymous attacker or FOFA-style mass scanner finds a reachable site with the plugin active on a vulnerable build.
  2. Scrape the public ajax nonce — WavePlayer prints `ajax_nonce` into any public page's HTML — the attacker regexes it out. Not an auth barrier.
  3. create_local_copy reachable unauthenticated? — The AJAX action has no capability check. If reachable, the anonymous POST proceeds to the file-copy sink.
  4. POST create_local_copy with a remote PHP url — Body carries `nonce` + `url=http(s)://attacker-host/payload`. No file-type/path validation (CWE-434).
  5. PHP written to wp-content/uploads/peaks/external/ — Payload lands in a predictable, web-served, PHP-executable directory; the response even discloses the path.
  6. Request the webshell → unauthenticated RCE — Directly requesting the dropped .php executes it — full pre-auth remote code execution in ~two requests.
  7. Persistence &amp; access resale — Seen in WP-SHELLSTORM: webshells, a VShell backdoor, access packaged and resold. Patching the plugin does NOT evict this.
  8. Prevent: update to 3.8.0 / disable plugin — Update to WavePlayer &gt;= 3.8.0, or deactivate it until you can. The only real fix.
  9. Detect: WAF block + FIM on uploads/*.php — Block unauth POSTs carrying create_local_copy + off-site url; alert on any new .php under wp-content/uploads/; disable PHP execution there.

Am I affected?

WavePlayer is a paid CodeCanyon plugin, so it won't surface in wordpress.org-based scanners the way free plugins do — check the plugin folder and admin screen directly. Anything below 3.8.0 is vulnerable; the fix is 3.8.0.

WavePlayer versionStatus
≤ 3.7.0 (all builds before 3.8.0)Vulnerable — unauthenticated arbitrary upload → RCE
3.8.0 and laterFixed — update here

Exploited in the wild — the WP-SHELLSTORM campaign

This is not a theoretical bug. Researchers who found an exposed attacker server documented a mass-compromise operation dubbed WP-SHELLSTORM, and WavePlayer's flaw is named among the ~27 plugin CVEs it weaponized to drop webshells. Australia's national cyber agency (ACSC) later warned about the same global campaign and listed this CVE among the exploited plugins (SOCRadar, The Hacker News, Cyber Daily).

Timeline

Disclosure → exploitation

  1. Advisory + patch
    WPScan publishes the flaw; fixed in 3.8.0 (credited to @zdenys).
    source
  2. NVD published
    CVSS 9.8 (CISA-ADP), CWE-434.
    source
  3. Public PoC
    A weaponized proof-of-concept appears publicly, lowering the bar to mass exploitation.
  4. WP-SHELLSTORM
    WordPress mass-hacking phase; WavePlayer among ~27 weaponized plugin CVEs.
    source
  5. ACSC advisory
    Australia warns of the global CMS campaign and lists this CVE.
    source
  6. Not on CISA KEV
    Still absent from KEV despite documented mass exploitation.

The part that should worry triage teams

Two signals a lot of teams lean on both said skip it. EPSS sat around 0.4% (~34th percentile) and the flaw is not on CISA KEV — while attackers were mass-scanning for it. That's not a knock on those signals so much as a reminder of what they measure: EPSS is trained on observed telemetry, so obscure commercial-plugin bugs stay low until enough exploitation data feeds back in, and CISA rarely adds individual WordPress-plugin CVEs to KEV even during active campaigns (Wordfence).

Detection & hunting

Hunt two things: the exploit request and the file it drops. In web access logs, look for unauthenticated POSTs to the create_local_copy action carrying a url parameter that points at an external host. On disk, treat any new .php under wp-content/uploads/ as suspicious — the PoC writes to wp-content/uploads/peaks/external/. Note there is currently no public Nuclei template for this CVE, so a template-only scan will give you a false all-clear; fall back to plugin-inventory and asset-path fingerprinting.

  • Exposure: confirm whether WavePlayer is installed and its version (wp plugin get waveplayer or the plugin header/readme); < 3.8.0 is vulnerable.
  • Request hunt: access-log POSTs to create_local_copy with url=http(s)://… off-site.
  • Drop hunt / FIM: new .php files under wp-content/uploads/** — especially …/peaks/external/.
  • Assume-compromise: if the site was reachable on a vulnerable build, check for webshells, added admin users, and modified core/plugin files before closing the ticket.
# Virtual patch + hardening while you roll out 3.8.0
# 1) Block the unauth exploit request at the WAF/proxy (sketch):
#    deny POST where arg wvpl-ajax == create_local_copy AND arg url matches ^https?://

# 2) Neutralise the RCE even if a file is written — no PHP under uploads:
location ~* /wp-content/uploads/.*\.php$ { deny all; }

What to do now

  1. Update WavePlayer to 3.8.0 or later via the vendor's licensed-update channel, and confirm the build actually moved.
  2. Can't patch this hour? Virtual-patch it: block the create_local_copy action for unauthenticated requests and deny .php execution under wp-content/uploads/. Deactivating the plugin is the safest stopgap.
  3. If it was exposed: run a compromise assessment — hunt webshells, rotate WordPress salts and admin credentials, and review for persistence. A patch removes the bug, not an attacker who already dropped a shell.

FAQ

Is CVE-2025-12057 being exploited?
Yes. It's named among the plugin flaws weaponized in the WP-SHELLSTORM mass-compromise campaign, and there's a public proof-of-concept. It is not on CISA KEV as of 2026-07-14, and its EPSS is low (~0.4%) — neither of which means it's safe.
Do I need to be logged in to exploit it?
No. The vulnerable create_local_copy action has no authorization check, and the WordPress nonce it uses is printed on public pages, so it behaves as a fully unauthenticated flaw.
How do I fix it?
Update WavePlayer to 3.8.0 or later. If you can't immediately, block the action at your WAF and disable PHP execution under wp-content/uploads/, or deactivate the plugin. Check a live score and details on the CVE page.
I patched — am I safe?
You've closed the bug, but if the site was internet-facing on a vulnerable build, assume a webshell may already exist. Hunt for new .php files under uploads and rotate secrets before you consider it resolved.

Sources