New24/7 monitoring and daily cloud backups now included in every Shield Pro plan.

Security12 August 202611 min read

WordPress plugin supply chain attack: BdThemes plugins created rogue admins

Share

A WordPress plugin supply chain attack hit BdThemes in August 2026. The plugin files on WordPress.org stayed clean. A promotional JSON feed did not. Logged-in administrators then grew extra admin accounts they never created. If you run Element Pack, Prime Slider, or another BdThemes plugin, check the site even if nothing looks wrong.

Ran a BdThemes plugin?

Cleaning the vendor feed does not clean a site that already got a hidden admin or webshell. If you want a human to hunt for that, we do WordPress malware removal from £99.99.

Get the site checked

What a WordPress plugin supply chain attack actually is

Most people picture a supply chain attack as “someone uploaded a bad plugin update.” That does happen. A ZIP on WordPress.org gets swapped, sites auto-update, and the malware arrives with a version bump.

The BdThemes case is the other flavour, and it is worse in one specific way. Nothing in the plugin repository had to change. The plugins already trusted a remote promotional feed. Attackers poisoned that feed. Every time a logged-in admin opened wp-admin, the dashboard fetched the poisoned JSON and ran attacker JavaScript in the admin’s own browser session.

You did not click a phishing link. You did not install a random ZIP from an email. Logging into wp-admin was enough. That is why this WordPress plugin supply chain attack spread quietly.

What happened with BdThemes

BdThemes makes Elementor add-ons a lot of sites already have installed: Element Pack, Prime Slider, Pixel Gallery, Ultimate Post Kit, Ultimate Store Kit, plus a couple of smaller tools. Element Pack alone sits north of 100,000 active installs on WordPress.org.

Those plugins share a banner component (researchers call it Biggopti) that pulls “summer sale” style notices from a vendor API. The API was not a clever application server. It was static JSON in object storage, sitting behind Cloudflare. Someone got write access to that bucket and replaced the legitimate notices with a payload.

Wordfence was notified on 7 August 2026 after seeing the traffic in the wild. The WordPress Plugins team then closed the affected listings pending review. By 8 August the poisoned endpoints were serving clean JSON again. BleepingComputer has a useful news round-up if you want the timeline in one place.

Cleaning the feed is not the same as cleaning your site. Anything planted between late June and 8 August is still there until someone looks.

Which plugins were in the blast radius

If any of these are installed, treat the site as in-scope. Free or premium does not matter. The banner code is what mattered:

  • Element Pack Addons for Elementor (bdthemes-element-pack-lite)
  • Prime Slider Addons for Elementor (bdthemes-prime-slider-lite)
  • Pixel Gallery Addons for Elementor (pixel-gallery)
  • Ultimate Post Kit Addons for Elementor (ultimate-post-kit)
  • Ultimate Store Kit (ultimate-store-kit)
  • Live Copy Paste for Elementor (live-copy-paste)
  • Smart Admin Assistant (smart-admin-assistant)

Wordfence scored the underlying XSS as medium (CVSS 5.4) and listed it as unpatched when they published. That sounds mild until you remember where it ran: inside an already-authenticated administrator session, on every wp-admin page load.

How the attack created rogue WordPress admins

You do not need the exploit write-up to defend the site. The shape is enough.

  1. A coding gap in the banner. A field from the remote JSON was dropped into an HTML id attribute without escaping. That bug landed in March 2026. Later releases sanitised the banner body and still left the id open.
  2. Poisoned JSON instead of a plugin update. With write access to the vendor bucket, attackers did not need to touch WordPress.org. The next admin page load fetched their payload.
  3. JavaScript in your admin session. The script used the logged-in administrator’s own nonce to create a new Administrator user. One variant used predictable usernames starting with bd_ and an @wordpress.org email. Another hid the new account from the Users screen.
  4. A fake plugin, then a backdoor. A ZIP with a boring name (researchers saw things like wp-smart-thumbnails) landed through the normal plugin uploader. Inside it: a webshell. That then dropped must-use plugins for persistence, including a magic-login style backdoor.

If that last stretch sounds familiar, it should. WordPress XSS2Shell is a different bug, in WordPress core, but the idea is the same: XSS in an admin context is how you turn “a script on a page” into “they own the site.”

Why file scans missed this WordPress plugin supply chain attack

Integrity checkers compare plugin files with WordPress.org. These files matched. No update was required. No file on disk had to change for the first stage to fire.

That is the part that should make site owners sit up. A lot of “we are fine” habits assume malware arrives as a dirty PHP file. Here the first stage lived in a JSON response the plugin asked for on purpose. File hashes stay green. The Users list can stay green too, because one of the persistence modules hooked database queries and hid the rogue accounts.

If you only glance at Dashboard > Users, you can miss the whole thing. Check the database, or use WP-CLI, or look at the wp_users table from the host. Do not trust the screen that the malware was written to lie to.

How to check your site after the BdThemes incident

Wordfence’s earliest possible campaign date is 23 June 2026, based on timestamps in the poisoned notices. The feed was clean again on 8 August. If a BdThemes plugin was active in that window, and an administrator used wp-admin, do this checklist. None of it needs a scanner licence.

1. Look for users you did not create

Hunt for Administrator accounts you do not recognise, especially:

  • Usernames starting with bd_ followed by six letters or numbers
  • Emails on @wordpress.org or @developer.wordpress.org that you did not add
  • Admins that appear in the database but not in wp-admin

WP-CLI is the honest view: wp user list --role=administrator. If you do not have SSH, phpMyAdmin or your host’s database tool works. Sort wp_users by user_registered and look at anything from late June onwards.

2. Look at plugins, including ones you never activated

  • Folders you did not install, with friendly names like wp-smart-thumbnails
  • A file named emer-run.php anywhere under wp-content
  • Must-use plugins under wp-content/mu-plugins, especially names like class-wp-token-validate.php, class-wp-query-*.php, or wp-cache-optimizer.php

Must-use plugins load automatically. They do not show up in the normal Plugins screen the way a regular plugin does. If you never use that folder, it should be empty or only contain what you put there.

3. Check the options table

Researchers flagged two database options used as compromise flags: fz_emer_login_tokens and fz_emer_done_v1. If either exists, treat the site as compromised even if the dashboard looks calm.

4. Do not stop at “the plugin is closed now”

WordPress.org closing the listing stops new installs. It does not uninstall the plugin, and it does not remove a backdoor that already landed. Same for the cleaned API. That only stops new infections from this particular feed.

What to do if you find a rogue admin or webshell

If anything on that list shows up, stop poking at random files. Half-cleaning a backdoor is how it comes back next week.

  1. Take a backup of the current mess before you delete anything, so a cleaner can still see what was there. Then keep it off the public site.
  2. Remove the rogue users from the database, not only from the Users screen. Reset passwords for every remaining Administrator. Rotate hosting, FTP, database, and application passwords too. The Password Vault exists so you are not doing that over email.
  3. Delete the fake plugin and any must-use droppers. Search the whole wp-content tree for emer-run.php, not just the plugins folder.
  4. Clear those database options if they are present, after you have a copy.
  5. Review who is still signed in. WordPress sessions, application passwords, and any “magic login” style URL the backdoor used. Our own 2FA and Active Sessions post is about the BugShield account, but the habit is the same: a strange session is a warning, not the whole cleanup.

If that already feels like a lot, it is. This is the job in Fixing a Hacked Site, and it is the same work we did in the hacked WordPress site case study. A proper malware removal pass covers files, the database, and the entry point. Deleting one user and hoping is not that.

This keeps happening

BdThemes is not a one-off mood. The same few months brought CDN and update-flow compromises against other well-known WordPress products, including OptinMonster. Wordfence tied the command-and-control used here to the same actor behind that campaign and the Advanced Responsive Video Embedder incident.

The pattern is getting boring, which is the problem. Popular plugins talk to vendor APIs for licence checks, banners, changelog nags, and “news.” Those requests look legitimate. They use HTTPS. They come from a domain the plugin author owns. File integrity tools are not watching that JSON.

So a WordPress plugin supply chain attack no longer has to mean “the ZIP on WordPress.org went bad.” It can mean “the plugin phoned home, and home was having a worse day than you were.”

What we take from it at BugShield

We cannot promise a vendor’s object storage will never get stolen credentials. Nobody honest can. What we can do is treat “popular plugin, quiet dashboard” as a reason to look, not a reason to relax.

On Shield plans, managed plugin updates are not “click Update All and leave.” They sit next to monitoring, backups, and a human who can check users and mu-plugins when a campaign like this lands. Shield Pro adds malware scanning on top. If you only need the cleanup, request a one-off fix or go straight to malware removal.

If you ran a BdThemes plugin this summer, do the user and mu-plugins check today. The feed is clean. That does not mean the site is.