# BdThemes: A WordPress Supply Chain Attack That Changed No Code At All

## Summary

**Not a single source code file in the WordPress.org repository was modified.** No plugin update was released. No file on disk changed.

Yet rogue administrator accounts were created on victim sites, a PHP web shell was installed, and two backdoor modules were planted in the `mu-plugins` directory.

Attackers obtained write access to **BdThemes' own DigitalOcean Spaces bucket** — where the vendor stores the JSON data feeding a promotional banner system rendered in the WordPress admin dashboard — and replaced the legitimate content with payloads exploiting an existing XSS flaw in `Biggopti`, an internal library shipped with the plugins.

Seven plugins are affected. Element Pack alone shows more than **100,000 active installations** on WordPress.org, while BdThemes advertises a portfolio of over **350,000 active installs**.

The point that matters most for defenders: the WordPress security industry has spent fifteen years building file integrity tooling — hash comparison, unfamiliar file detection, plugin version diffing. **That entire layer is blind here**, because there is nothing to compare.

**Priority action: if your website runs any BdThemes plugin, treat it as compromised and immediately audit your user list for accounts with** `@wordpress.org` **email addresses or usernames beginning with** `bd_`**.**

* * *

## The Vulnerability: When CVSS 5.4 Becomes Full Site Takeover

![BdThemes attack overview](https://cyberpress.org/wp-content/uploads/2026/08/bdthemes-wordpress-supply-chain-attack-creates-rogue-admins-and-deploys-webshells-6a79a318e0c2a.webp align="center")

*Overview of the BdThemes supply chain campaign (source: Cyber Security News, based on Wordfence analysis).*

`Biggopti` is an internal component bundled with BdThemes plugins. Its job is entirely mundane: pull promotional banners from the vendor's API server — specifically JSON files stored in a DigitalOcean Spaces bucket sitting behind Cloudflare — and render them in the WordPress admin dashboard.

The flaw sits in the JSON response parsing: `Biggopti` **fails to safely escape the** `display_id` **value** before inserting it into an HTML `id` attribute. Notably, a neighbouring field in the same response **is sanitized correctly** — only this one was missed.

| Item | Detail |
| --- | --- |
| Component | `Biggopti` (internal, bundled with plugins) |
| Data source | Sigmative API, JSON on a DigitalOcean Spaces bucket |
| Vulnerable field | `display_id` — insufficient client-side escaping |
| Type | Cross-site scripting (XSS) |
| CVSS (Wordfence) | **5.4 — medium** |
| First introduced | 1 March 2026, in `bdthemes-prime-slider-lite` v4.1.9 |
| Trigger mechanism | `onanimationstart` handler, firing within **10 milliseconds** of page load |
| Trigger scope | **Every** `wp-admin` **page load** by any logged-in administrator |

This deserves separate attention. **5.4 is a methodologically correct score**, and read on its own it would sit near the bottom of most patch queues. But that score is calculated on an implicit assumption: that the data source — the vendor's own API — is trustworthy.

When that assumption collapses, the same flaw permits full site takeover. The CVSS scale has no field for "if upstream is compromised." That is a gap in the current scoring model, and it appears more often as modern software increasingly pulls dynamic data from external infrastructure.

## Timeline: Three Victims, One Actor

What makes this more than an isolated incident is Wordfence's assessment that the C2 infrastructure used here **is related to two other WordPress supply chain attacks in the preceding two months**.

| Date | Event |
| --- | --- |
| 1 Mar 2026 | The `display_id` XSS flaw is introduced in Prime Slider v4.1.9, then propagated to other BdThemes plugins |
| 14 Jun 2026 | **OptinMonster and TrustPulse** disclose an incident: a CDN credential was compromised and a tampered JavaScript file served from their own CDN |
| 23 Jun 2026 | Earliest possible start of the BdThemes campaign, per Wordfence's analysis of available records |
| 28 Jul 2026 | **Advanced Responsive Video Embedder (ARVE) 10.8.7** is backdoored; Wordfence's PRISM system detects it in **under two hours**; CVE-2026-18072, CVSS 9.8 |
| 7 Aug 2026 | Wordfence observes attacks through its WAF; signatures and firewall rules shipped to Premium, Care, Response and paid CLI customers |
| 7–8 Aug 2026 | The WordPress Plugins team closes all seven BdThemes plugins pending a full review |
| 8 Aug 2026 | Both poisoned API endpoints serve clean JSON again; Wordfence publishes its analysis |
| 11 Aug 2026 | Broad press coverage; BdThemes has still issued no official statement |

### The Shared Pattern

Placed side by side, the pattern across all three incidents is what belongs in an internal briefing:

|  | OptinMonster / TrustPulse | ARVE | BdThemes |
| --- | --- | --- | --- |
| Point of compromise | CDN API credential | Developer account commit access | Cloud storage credentials |
| Repository source modified? | No | **Yes** (v10.8.7) | No |
| Trigger condition | Logged-in administrator | A single HTTP request | Logged-in administrator |
| Outcome | Hidden admin account + concealed backdoor plugin | Unauthenticated admin access | Rogue admin + web shell + `mu-plugins` backdoors |

Two of three **never touched source code**. All three attacked the **delivery layer** rather than the code layer: a CDN key, a developer account, cloud storage credentials. And in two of them the payload only activated for logged-in administrators — a choice that avoids detection by ordinary visitors and automated scanners entirely.

Wordfence assesses the campaign's end goal as establishing **covert administrative persistence and remote code execution across WordPress environments at scale**.

* * *

## The Attack Chain

1.  Attackers obtain BdThemes' cloud credentials and gain write access to the vendor's DigitalOcean Spaces bucket.
    
2.  They replace legitimate JSON records with crafted payloads, planting malicious content in the `display_id` field.
    
3.  A logged-in WordPress administrator opens any `wp-admin` page on a site running a BdThemes plugin.
    
4.  `Biggopti` automatically fetches banner data from the API endpoint.
    
5.  The poisoned `display_id` is inserted unescaped into an HTML `id` attribute; an `onanimationstart` handler fires within 10 milliseconds.
    
6.  The main payload — a JavaScript file named `w2.js`, delivered via the `api-data-all-records` endpoint — begins executing inside the administrator's authenticated browser.
    
7.  `w2.js` contacts the C2 server at `ia-cdn[.]com/fz/c`, sending the victim site's origin to fetch targeting instructions. **If the C2 returns a** `skip` **or** `done` **status, execution aborts.**
    
8.  Using the active administrative session's REST API nonce, the script creates a rogue administrator account through the WordPress REST API.
    
9.  It downloads a fake plugin ZIP from the C2 — with an innocuous slug such as `wp-smart-thumbnails` — and installs it through **WordPress's standard plugin upload form**.
    
10.  That plugin contains a PHP web shell named `emer-run.php`.
     
11.  The web shell is invoked to install **two persistence modules into the** `mu-plugins` **directory** (Must-Use plugins, which are always active and cannot be disabled from the admin interface), with **file timestamps backdated to September 2025**.
     
12.  The first module is a **magic-login backdoor**: it grants unauthenticated administrative entry via the URL parameter `?_wplogin=<token>`, targeting **the site's longest-registered administrator account**.
     
13.  The second is an **anti-analysis stealth module**: it hooks WordPress database queries to conceal the rogue accounts from the admin user list and **excludes them from the displayed total user count**.
     
14.  Results of the whole operation are exfiltrated back to the C2 via `navigator.sendBeacon`. Steps 7 and 11 warrant separate comment.
     

**The** `skip`**/**`done` **mechanism in step 7** shows the attackers maintain a target list server-side and avoid re-running against already-processed sites. For incident responders this means **not observing activity does not mean the site was never targeted** — the C2 may simply have returned `done`.

**The file backdating in step 11** is a small but effective anti-forensic touch. An administrator reviewing the `mu-plugins` directory by modification time would see files that appear to predate even the introduction of the vulnerability itself, and would most likely skip past them.

### The Second Payload: Deterministic Credentials

An alternate payload named `x.js`, found hosted **on the plugin developer's own infrastructure** and served through the `api-data-records` endpoint, works differently.

Rather than creating accounts with random details, it **generates administrative credentials mathematically derived from the victim website's hostname**:

```plaintext
Username    bd_ + a 6-character base36 hash
Password    Bd@26! + hash + x
Email       an @wordpress.org address
```

Wordfence highlights the two-way consequence of this design, and both directions are worth remembering.

For the attacker: because the credentials are deterministic, they **do not need to store a centralised list of compromised sites**. Knowing the hostname is enough to recompute the login at any time. There is no victim database to be seized or leaked.

For defenders: incident responders **can compute the exact username and password to hunt for on a suspected domain**. That is a rare condition in incident response — you know precisely what you are looking for rather than guessing.

The choice of an `@wordpress.org` email address is also a calculated social detail: to an administrator glancing down a user list, the account reads as an official system account rather than an intruder.

* * *

## Affected Plugins

| Slug | Plugin name | Active installs |
| --- | --- | --- |
| `bdthemes-element-pack-lite` | Element Pack Addons for Elementor | **100,000+** |
| `live-copy-paste` | Live Copy Paste for Elementor | 6,000+ |
| `ultimate-store-kit` | Ultimate Store Kit – Addon For WooCommerce, EDD and Elementor | 6,000+ |
| `bdthemes-prime-slider-lite` | Prime Slider Addons for Elementor | Not published |
| `pixel-gallery` | Pixel Gallery Addons for Elementor | Not published |
| `ultimate-post-kit` | Ultimate Post Kit Addons for Elementor | Not published |
| `smart-admin-assistant` | Smart Admin Assistant – Dashboard and Site Enhancements | Not published |

All seven were closed on the official repository by the WordPress Plugins team on 7 or 8 August 2026, with a notice that they are unavailable pending a "full review."

* * *

## Indicators of Compromise

> Compiled from the Wordfence Threat Intelligence advisory of 8 August 2026 and public reporting reproducing its technical detail. Domains are defanged.

**C2 infrastructure and payloads**

```plaintext
ia-cdn[.]com/fz/c            # C2 endpoint receiving site origin, returning targeting instructions
                             # note the naming, designed to pass for a legitimate CDN service
 
w2.js                        # main payload, served via the api-data-all-records endpoint
x.js                         # alternate payload, hosted on BdThemes' own infrastructure,
                             # served via the api-data-records endpoint
 
api-data-all-records         # poisoned API endpoint (Sigmative API)
api-data-records             # poisoned API endpoint (Sigmative API)
```

**On-site artifacts**

```plaintext
# Web shell
emer-run.php                 # PHP web shell, installed via the fake plugin ZIP
 
# Fake plugin slug (observed example)
wp-smart-thumbnails          # neutral name, installed via the standard plugin upload form
 
# mu-plugins directory
Two unfamiliar files with timestamps backdated to September 2025:
  - magic-login backdoor module
  - anti-analysis module hiding users from the admin list
 
# Backdoor URL parameter
?_wplogin=<token>            # unauthenticated administrative entry,
                             # targeting the longest-registered admin account
 
# WordPress database options
fz_emer_login_tokens
fz_emer_done_v1
```

**Rogue administrator account pattern**

```plaintext
Username    bd_<6-character base36 hash>
Password    Bd@26!<hash>x
Email       <anything>@wordpress.org
 
# Because the credentials are deterministic per hostname, responders can
# precompute the exact values to hunt for on a given domain
```

**Behavioural indicators**

```plaintext
- Administrator accounts appearing outside your provisioning process, especially with @wordpress.org emails
- Plugins installed that nobody in the organisation installed
- A discrepancy between the displayed total user count and the actual row count in the database
- Files in mu-plugins whose timestamps do not match the site's deployment history
- Outbound requests to ia-cdn[.]com from an administrator's browser
```

**Related campaign activity (context)**

```plaintext
CVE-2026-18072    Advanced Responsive Video Embedder 10.8.7
                  CVSS 9.8 — Authentication Bypass via hardcoded backdoor
                  File: php/fn-update-check.php, function _arve_uc_init()
                  Parameters: _wplogin, _wpm
                  Detected by Wordfence PRISM in under 2 hours (28 July 2026)
                  ~20,000 active installations
 
OptinMonster / TrustPulse   CDN incident, disclosed 14 June 2026
                  CDN credential compromised, tampered JavaScript served from the CDN
                  Activated only for logged-in administrators
```

* * *

## MITRE ATT&CK Mapping

| Tactic | Technique ID | Technique Name | Observed in campaign |
| --- | --- | --- | --- |
| Initial Access | T1195.002 | Supply Chain Compromise: Software Supply Chain | Poisoning the vendor's JSON data stream |
| Resource Development | T1584 | Compromise Infrastructure | Write access obtained to BdThemes' own storage bucket |
| Resource Development | T1583.001 | Acquire Infrastructure: Domains | `ia-cdn[.]com` registered as C2 infrastructure |
| Execution | T1059.007 | Command and Scripting Interpreter: JavaScript | `w2.js` and `x.js` running in the administrator's browser |
| Defense Evasion | T1036.005 | Masquerading: Match Legitimate Name or Location | `wp-smart-thumbnails`; C2 domain posing as a CDN service |
| Credential Access | T1185 | Browser Session Hijacking | Abusing the active admin session's REST API nonce |
| Persistence | T1136 | Create Account | Rogue administrator created via the REST API |
| Persistence | T1505.003 | Server Software Component: Web Shell | `emer-run.php` |
| Persistence | T1505 | Server Software Component | Two backdoor modules in `mu-plugins` |
| Persistence | T1098 | Account Manipulation | Targeting and abusing the longest-registered admin account |
| Defense Evasion | T1070.006 | Indicator Removal: Timestomp | `mu-plugins` files backdated to September 2025 |
| Defense Evasion | T1564 | Hide Artifacts | Hooking database queries to conceal rogue accounts from the user list |
| Defense Evasion | T1027 | Obfuscated Files or Information | JavaScript payload embedded in a JSON response |
| Exfiltration | T1041 | Exfiltration Over C2 Channel | Results sent to C2 via `navigator.sendBeacon` |
| Impact | T1078 | Valid Accounts | Maintaining persistent administrative access |

* * *

## Assessment

**The WordPress security industry built its entire defensive posture around one assumption: malicious code lives in files.**

That was a reasonable assumption and held true for years. A backdoored plugin means changed files. A compromised site means unfamiliar files appear. So the tooling was built accordingly: compare plugin file hashes against the official repository, scan directories for unknown files, alert on anomalous updates. WordPress.org provides the known-good baseline, and the model works.

This campaign put its payload in exactly the place nothing scans: **a JSON response**. No file to hash. No diff to compare. No update to review. The plugin on disk is byte-for-byte identical to the official repository copy — and still executes the attacker's code every time an administrator opens the dashboard.

**But there is a notable paradox here, and it favours defenders.** Precisely because the technique is unusual, it leaves very specific and easily verified traces: one URL parameter name, two database option names, a computable username pattern. Hard to catch with automated scanners, but **verifiable by hand in fifteen minutes if you know where to look**. This is not the kind of incident that requires expensive tooling to investigate.

**On the severity scoring gap.** The XSS flaw scores 5.4 — medium. In most organisations' patch queue, that number sits below the priority threshold. But the score reflects danger *assuming the data source is trustworthy*. When the vendor itself is compromised, the same flaw enables full site takeover.

This is an increasingly common problem rather than an edge case. Modern software constantly pulls dynamic data from external infrastructure: promotional banners, update notices, remote configuration, telemetry. Every such feed is a channel your code trusts by default, and the current scoring model has nowhere to record that risk.

**The awkward position site owners are in right now.** The plugins are closed on WordPress.org, meaning **there is no update path through the official channel**. The vulnerability was unpatched when the report was published, and the vendor has issued no statement. That leaves site owners with an uncomfortable choice: keep the plugins and carry an unpatched vulnerability, or remove them and break much of the site's Elementor layout.

That the API endpoints have served clean data since 8 August is positive but not a fix — it depends on the attackers not regaining write access to the bucket, which is entirely outside your control.

### Relevance for Vietnam

**The WordPress plus Elementor combination is extremely common domestically.** It is the default platform for small and medium business websites, online shops, landing pages and company profile sites in Vietnam — low cost, easy to find people who can build it, and no technical capability required to run it. Element Pack is among the most widely used Elementor addon suites in that ecosystem.

**Two market characteristics make the risk worse here.**

The first is the **build-and-hand-over agency model**. A great many business websites are built by an outside firm, handed over, and the contract ends. After that nobody tracks which plugins are running, at what version, or whether patches exist. The site keeps working normally for years — and that is exactly the condition this campaign needs.

The second is **shared hosting**. With the low-cost hosting packages common domestically, multiple websites frequently sit under one account or on one server. A site where an attacker gained administrative access and installed a web shell can become a stepping stone to the others in the same scope.

**A very simple operational question to test yourself against:** who in your organisation knows which plugins your company website runs, and at which versions? For most small and medium businesses we encounter, the answer is nobody — which means that even when this advisory reaches the right person, they still cannot answer "are we affected?"

If your organisation lacks a plugin inventory for the websites it operates, building one is worth doing before addressing this specific incident.

* * *

## Recommendations

*   **If a website runs any BdThemes plugin, treat it as compromised** until proven otherwise — particularly sites where administrators logged into the dashboard regularly between 23 June and 8 August 2026.
    
*   **Hunt four specific artifacts:** accounts with `@wordpress.org` emails or usernames beginning `bd_`; unfamiliar files in `mu-plugins` (ignore timestamps, which are backdated); the `emer-run.php` web shell; and the `fz_emer_login_tokens` and `fz_emer_done_v1` entries in the database options table.
    
*   **Rotate all administrative credentials and invalidate active sessions** — the administrator's authenticated session is what was abused to carry out the attack, so deleting the rogue accounts alone is not enough.
    
*   **Compare the displayed user count in the interface against the actual row count in** `wp_users` — the attacker's stealth module hides accounts from both, so a discrepancy between database and interface is a direct indicator.
    
*   **Build and maintain a plugin inventory for every website you operate**, with versions and an accountable owner — without it you cannot answer the most basic question when an advisory lands.
    
*   **For dynamic external data feeds generally:** review which components in your systems automatically fetch and render third-party content in a privileged context, and treat those feeds as untrusted input rather than a vouched-for source.
    

* * *

## References

*   Wordfence Threat Intelligence — [PSA: Supply Chain Compromise in BdThemes Ecosystem via Poisoned API Response](https://www.wordfence.com/blog/2026/08/psa-supply-chain-compromise-in-bdthemes-ecosystem-via-poisoned-api-response/) (8 August 2026) — original advisory
    
*   BleepingComputer — [BdThemes plugins supply-chain hack creates rogue WordPress admins](https://www.bleepingcomputer.com/news/security/bdthemes-plugins-supply-chain-hack-creates-rogue-wordpress-admins/)
    
*   The Hacker News — [BdThemes Supply Chain Attack Poisons JSON to Create Rogue WordPress Admins](https://thehackernews.com/2026/08/bdthemes-supply-chain-attack-poisons.html) (11 August 2026)
    
*   Cyber Security News — [BDThemes WordPress Supply Chain Attack Creates Rogue Admins and Deploys Webshells](https://cyberpress.org/bdthemes-wordpress-supply-chain-attack/) (10 August 2026)
    
*   Infosecurity Magazine — [WordPress Plugins Compromised Without a Single File Change](https://www.infosecurity-magazine.com/news/bdthemes-wordpress-poisoned-api/)
    
*   Wordfence — [Wordfence PRISM Detected Backdoored WordPress Plugin within Two Hours of it Being Introduced](https://www.wordfence.com/blog/2026/07/wordfence-prism-detected-backdoored-wordpress-plugin-within-two-hours-of-it-being-introduced/) (ARVE, CVE-2026-18072)
    
*   GitHub Advisory Database — [GHSA-45wh-rxq4-jqc6 / CVE-2026-18072](https://github.com/advisories/GHSA-45wh-rxq4-jqc6)
    
*   TrustPulse — [Security Incident: Tampered Script Served via TrustPulse and OptinMonster](https://trustpulse.com/2026/06/14/security-incident-tampered-script-served-via-trustpulse-and-optinmonster/) (14 June 2026)
    
*   GBHackers — [WordPress Supply Chain Attack Exploits BdThemes Plugins](https://gbhackers.com/wordpress-supply-chain-attack-exploits-bdthemes-plugins/)
