Software supply chain attacks usually mean a compromised build pipeline, a hijacked maintainer account, or a poisoned package on a registry - the kind of thing a code review or a dependency scan is built to catch. The BdThemes campaign, disclosed by Wordfence on 7 August, used none of those routes. According to BleepingComputer's write-up and The Hacker News' coverage, the plugin code itself - Element Pack Addons for Elementor, Prime Slider, Pixel Gallery, Ultimate Post Kit, Ultimate Store Kit, Live Copy Paste and Smart Admin Assistant, together installed on more than 350,000 sites - was never modified in the WordPress.org repository. What attackers compromised instead was a static JSON data stream, hosted in a DigitalOcean Spaces bucket behind Cloudflare, that every one of those plugins fetches automatically to render an internal promotional banner system called "Biggopti."
An output-escaping bug from March became a loaded weapon in June
The root cause traces back further than the attack itself. A coding flaw introduced in BdThemes' Biggop Library in March 2026 left the JSON response-parsing code without sufficient output escaping, creating a stored cross-site scripting hole that nobody needed to find in the plugin's own source to exploit - only in the feed it trusted. Once attackers had write access to that storage bucket, timestamps in the poisoned promotional records suggest the campaign itself may have started as early as 23 June, running quietly for weeks before Wordfence caught it. The injected JavaScript executed inside logged-in administrator sessions the moment the banner rendered, which is the detail that makes this pattern distinctive: no plugin vulnerability, no phishing email, no credential theft. An admin logging into their own WordPress dashboard was enough to trigger it.
What the payload actually did once it landed
The script's job, once it fired in an admin's browser, was to create a new WordPress administrator account through the REST API, then hide that account from the standard user list by manipulating the database query used to populate it - a rogue admin that wouldn't show up on a routine check of who has access. From there it dropped a webshell named emer-run.php for persistence and pulled a secondary payload, w2.js, that installed a fake plugin as a further foothold. Wordfence and the vendor moved to clean the compromised API endpoints on 8 August, a day after disclosure, and the affected plugins were pulled from WordPress.org pending investigation. That's a fast response by supply chain standards - it doesn't undo the weeks the poisoned feed was live, or tell any individual site owner whether their install was one of the ones that got hit before the cleanup.
The lesson isn't "audit your plugins harder"
A dependency scan or a code audit of Element Pack's WordPress.org listing would have found nothing wrong, because nothing in that listing was wrong. The vulnerability lived in a runtime trust relationship most site owners don't know exists: a plugin phoning home to a vendor-controlled feed for content that isn't code, doesn't look like code, and gets rendered anyway inside a privileged browser session. We saw the same structural problem, inverted, in the ChainDrop npm worm that rewrote trusted packages and re-signed the fakes with valid provenance - different ecosystem, different delivery mechanism, same underlying failure: verification stopped at the point everyone assumed was safe, not at the point actual code executed. Any inventory of "third-party code we trust" that stops at package.json or a plugin's own repository is incomplete if that code also pulls in live data, config, or promotional content from somewhere else at runtime.
- If you run any of the seven affected BdThemes plugins, update immediately, then check for unexpected administrator accounts and search your filesystem for
emer-run.phporw2.jsregardless of update status. - Extend your WordPress plugin inventory to cover remote feeds and "phone home" content - promotional banners, license checks, update notices - not just the plugin code itself.
- Restrict outbound requests from admin-facing pages to a known allowlist of vendor domains where your hosting setup allows it, so a compromised third-party bucket can't silently become a delivery channel.
- Review admin account lists on every WordPress site under management this week specifically for accounts that don't correspond to a known person - not just as part of the next scheduled audit.
A plugin that has never had a single line of malicious code committed to it can still be the reason your admin panel gets a new administrator you didn't create. If you need help mapping the runtime trust relationships in your own web estate, not just its code dependencies, email sales@halfteck.com.