Hoppa till innehåll
BdThemes drabbat av supply chain-angrepp via förgiftat API
Maja Lindberg
Maja Lindberg 9 August 2026 · 10 min läsning

BdThemes drabbat av supply chain-angrepp via förgiftat API

En komprometterad fjärrmatad JSON-ström har använts för att angripa WordPress-administratörer som har något av sju BdThemes-tillägg installerat. Angreppet ändrar inga filer i WordPress.org:s repository och kräver ingen tilläggsuppdatering, men kan ändå skapa dolda administratörskonton, installera webshells och etablera långvarig åtkomst.

Pågående supply chain-angrepp

Avinstallera eller inaktivera berörda BdThemes-tillägg tills vidare och undersök webbplatsen om en administratör har besökt wp-admin sedan den 23 juni 2026. Tilläggen är tillfälligt stängda i WordPress tilläggskatalog medan de granskas.

En förgiftad API-ström kringgår filkontroller

Angreppet är en supply chain-kompromettering, alltså att angriparen utnyttjar en leverantör eller en delad komponent för att nå dess användare. I det här fallet ändrade angriparen inte en enda källkodsfil i WordPress.org:s officiella repository. I stället fick angriparen skrivåtkomst till BdThemes lagringsyta och ersatte legitima JSON-svar med skadliga poster.

BdThemes-tilläggen innehåller den interna komponenten Biggopti. Komponenten hämtar kampanjbanners från leverantörens API och visar dem i WordPress adminpanel. API:t använder statiska JSON-filer från en DigitalOcean Spaces-bucket bakom Cloudflare, inte en dynamisk applikationsserver.

Det innebär att vanliga integritetskontroller av filer inte ser angreppet: inga tilläggsfiler ändras på disken. En brandvägg för webbapplikationer har också begränsad insyn, eftersom den skadliga JavaScript-koden körs i en redan autentiserad administratörs webbläsare när den läser in en wp-admin-sida.

Berörda tillägg och sårbarhetens status

Sårbarheten finns i Biggopti-biblioteket i flera versioner. Den har CVSS-betyget 5,4 (Medium) och saknar korrigering. Bristen är en cross-site scripting-sårbarhet (XSS), där otillräcklig output escaping av parametern display_id från Sigmative API låter den som styr API-servern injicera skript som körs när någon öppnar den injicerade sidan.

Följande tillägg omfattas av incidenten:

  • 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 – Addon For WooCommerce, EDD and Elementor – ultimate-store-kit
  • Live Copy Paste for Elementor – live-copy-paste
  • Smart Admin Assistant – smart-admin-assistant

Så fungerar XSS-bristen

Varje BdThemes-tillägg som använder Biggopti laddar ett JavaScript-bibliotek under hooken admin_init. Skriptet körs därför ovillkorligen vid varje sidladdning i wp-admin och hämtar bannerdata från leverantörens API-endpoint.

När skriptet bygger ett HTML-element i DOM:en lägger det in fältet display_id direkt i attributet id. Koden escape:ar inte värdet på klientsidan, så ett manipulerat JSON-svar kan avsluta id-attributet och injicera ytterligare HTML-attribut eller JavaScript-händelser.

// display_id används utan escaping
var f = t.display_id || t.id || "default";
var m = "bdt-admin-biggopti-api-biggopti-" + f;
A = 'id="' + m + '"';

I samma kod hanterar komponenten däremot attributet data-display-id med escaping. Funktionen ersätter &, <, >, och dubbla citattecken med HTML-entiteter. Den senare skyddsåtgärden omfattar inte det sårbara id-attributet.

function escapeAttribute(value) {
  return (value || "")
    .replace(/&/g, "&amp;")
    .replace(/</g, "&lt;")
    .replace(/>/g, "&gt;")
    .replace(/"/g, "&quot;");
}

SVN-historiken visar att Prime Slider version 4.1.9, SVN-revision r3471891, införde den oescape:ade attributinjektionen den 1 mars 2026. BdThemes förde sedan över koden till fler tillägg. Senare versioner lade till en DOMParser-baserad sanerare för bannerns innehållsfält, som tar bort farliga HTML-taggar och inline-händelsehanterare. Saneraren åtgärdade dock inte id-attributet.

De förgiftade JSON-posterna använde display_id för att bryta sig ur attributet och lägga till en onanimationstart-hanterare. En CSS-animation aktiverar händelsen efter ungefär 10 millisekunder, utan synlig interaktion, när en inloggad administratör öppnar valfri sida i adminpanelen. Händelsehanteraren hämtar sedan extern JavaScript-kod från angriparens infrastruktur.

Angreppets två payloadkedjor

Angriparen använde olika payloads beroende på vilket API som ett tillägg anropade. Den primära payloaden w2.js riktade sig till tillägg som läste endpointen api-data-all-records. Den alternativa payloaden x.js låg direkt på BdThemes infrastruktur och riktade sig till tillägg som läste api-data-records.

Primär payload: w2.js

När w2.js kör i den inloggade administratörens session utför den följande kedja:

  1. Verifiera C2-servern: Skriptet kontaktar ia-cdn[.]com/fz/c och skickar webbplatsens origin för att hämta instruktioner om målval. Skriptet avbryter om C2-servern svarar med statusen skip eller done.
  2. Skapa ett obehörigt administratörskonto: Skriptet använder X-WP-Nonce från den aktiva admins session för att skapa en ny administratör via WordPress REST API. Om det inte fungerar faller skriptet tillbaka till vanliga formulärinskick.
  3. Installera en webshell: Skriptet hämtar en falsk tilläggs-ZIP från C2-servern och laddar upp den via WordPress vanliga formulär för tilläggsuppladdning. Det falska tillägget maskerar sig som wp-smart-thumbnails eller ett liknande neutralt slug-namn och innehåller webshellen emer-run.php, som angriparen kan anropa direkt via URL.
  4. Installera bakdörrar som Must-Use-tillägg: När angriparen anropar emer-run.php installerar den två persistensmoduler i katalogen för Must-Use-tillägg. De två analyserade proverna hade tidsstämplats bakåt till september 2025 för att smälta in bland legitima filsystemstider, men filnamnen kan variera mellan infektioner. Den första modulen erbjuder magic login via URL-parametern ?_wplogin=<token> utan autentisering och riktar sig mot webbplatsens äldsta registrerade administratör. Den andra modulen döljer spår genom att hooka in i WordPress databasfrågor, gömma de obehöriga kontona från användarlistan och minska det totala användarantalet i motsvarande grad.
  5. Exfiltrera resultat: Skriptet skickar resultaten från varje exekveringsfas till C2-servern med navigator.sendBeacon.

Alternativ payload: x.js

x.js skapar förutsägbara administratörsuppgifter från den angripna webbplatsens värdnamn. Algoritmen beräknar ett heltalshash från varje tecken i värdnamnet, omvandlar det absoluta värdet till base36 och använder de sex första tecknen.

function makeCreds() {
  var host = siteKey();
  var hash = 0;

  for (var i = 0; i < host.length; i++) {
    hash = ((hash << 5) - hash + host.charCodeAt(i)) | 0;
  }

  var n = Math.abs(hash).toString(36).slice(0, 6);
  return {
    user: "bd_" + n,
    pass: "Bd@26!" + n + "x"
  };
}

Skriptet använder användarnamnet bd_ följt av hashen, lösenordet Bd@26! följt av hashen och x, samt en e-postadress med domänen @wordpress.org. Eftersom uppgifterna är deterministiska behöver angriparen inte spara en central lista över angripna webbplatser. Vid incidenthantering kan du i stället beräkna det förväntade användarnamnet och lösenordet för en misstänkt domän.

Därefter hämtar skriptet /wp-admin/user-new.php, extraherar nonce-värdet för att skapa användare och skickar ett formulär som tilldelar rollen administrator. Skriptet sparar en lokal flagga i localStorage när det kan göra det, rapporterar användarnamn, lösenord, webbplatsens origin, logout-URL, aktuell sida och resultatet till C2-servern samt använder sendBeacon eller en fetch-begäran med no-cors som reservväg.

Omfattning och bakomliggande infrastruktur

C2-domänen kopplas till samma aktörer som låg bakom supply chain-angreppen mot Advanced Responsive Video Embedder och OptinMonster under de två föregående månaderna. Kampanjen har som mål att etablera utbredd, tyst administratörspersistens och fjärrkörning av kod i WordPress-miljöer.

Angriparen behövde inte få åtkomst till enskilda WordPress-webbplatser. Det räckte att förgifta ett betrott flöde för kampanjdata och utnyttja visningskoden i administratörens webbläsare. Att de skadliga JSON-posterna och x.js laddades upp direkt till leverantörens bucket tyder på en allvarlig kompromettering av BdThemes molnlagringsuppgifter eller interna infrastruktur.

Indikatorer på kompromettering

Sök igenom webbservern, WordPress-installationen och databasen efter följande indikatorer. De förgiftade API-endpointarna är rensade, men en tidigare körd payload kan ha lämnat kvar konton och persistensmekanismer.

Externa resurser

  • Primär payload: ia-cdn[.]com/fz/w2.js
  • C2-endpoint för beacon-data: ia-cdn[.]com/fz/c
  • Förgiftad leverantörsendpoint, nu rensad: api[.]sigmative[.]io/prod/store/api/biggopti/api-data-all-records
  • Förgiftad leverantörsendpoint, nu rensad: api[.]sigmative[.]io/prod/store/api/biggopti/api-data-records
  • Förgiftad leverantörsresurs, nu rensad: api[.]sigmative[.]io/prod/store/api/biggopti/x.js

Filer, databasposter och konton

  • Webshell: emer-run.php – MD5: 1024732009983dd5e54b4cf5593f04d4
  • Magic-login-bakdörr som MU-tillägg: class-wp-token-validate.php – MD5: 7719cd98a35ffad2771f26d1ceab7d27
  • Stealth-modul som MU-tillägg: class-wp-query-9d127ff3.php, eller liknande namn enligt mönstret class-wp-query-*.php – MD5: 9aadc3e5c5242b273bd17c5bdc358845
  • MU-tillägget ”Health Check”: wp-cache-optimizer.php – MD5: e450ae5bc4bfc0d960dded06a76bb8e9
  • Databasoptionen fz_emer_login_tokens, som lagrar token för magic login.
  • Databasoptionen fz_emer_done_v1, som markerar att komprometteringen har slutförts.
  • Konton med e-postdomänen @wordpress.org eller @developer.wordpress.org.
  • Användarnamn som matchar bd_ följt av sex alfanumeriska tecken.

Tidslinje

  • 1 mars 2026: Biggoptis API-JavaScript läggs till i Prime Slider 4.1.9, SVN r3471891. display_id hamnar oescape:at i ett id-attribut och tillägget använder endpointen api-data-records.
  • 10 maj 2026: Endpointen byts till api-data-all-records. En DOMParser-sanering läggs till för innehållsfältet, men id-attributet lämnas oescape:at.
  • 23 juni 2026: start_date i den förgiftade API-kampanjen anges för meddelandet ”Summer Sale”. Detta är det tidigaste möjliga datumet då XSS-angreppet kan ha varit aktivt.
  • 6 augusti 2026, 22:40 UTC: Senaste ändringstid för den förgiftade api-data-records-resursen.
  • 7 augusti 2026, 09:11 UTC: Senaste ändringstid för den förgiftade api-data-all-records-resursen.
  • 7 augusti 2026: Angreppet observeras i praktiken och säkerhetsteamet får information om incidenten.
  • 7 augusti 2026: WordPress tilläggskatalog stänger de berörda tilläggen i väntan på granskning.
  • 7 augusti 2026, 16:56 UTC: Utredningen samlar in artefakter.
  • 8 augusti 2026: Båda API-endpointarna returnerar åter rena JSON-svar.

Granska installationen nu

Börja med att inventera om något av de sju tilläggen finns eller har funnits på webbplatsen. Granska sedan användarlistan direkt i databasen, inte bara i WordPress adminpanel, eftersom stealth-modulen kan dölja konton och justera användarantalen. Kontrollera även katalogerna för vanliga tillägg och Must-Use-tillägg samt optionstabellen efter samtliga indikatorer ovan.

Wordfence Premium, Care, Response och betalande Wordfence CLI-kunder fick signaturer för skadlig kod och WAF-regler den 7 augusti 2026. Wordfence Free och kostnadsfria Wordfence CLI får samma signaturer och regler efter den vanliga fördröjningen på 30 dagar. En filsökning räcker dock inte ensam, eftersom den initiala komprometteringen inte behöver ändra några befintliga tilläggsfiler.

Gå med i HelloWP-communityn!

Chatta med oss om WordPress, webbutveckling och dela erfarenheter med andra utvecklare.

- medlemmar
- online
Gå med

Vi använder cookies för att förbättra din upplevelse. Genom att fortsätta godkänner du vår Cookiepolicy.