Към съдържанието
BdThemes supply chain атака през JSON API: как да провериш сайта си
Мария Иванова
Мария Иванова 9 August 2026 · 3 мин. четене

BdThemes supply chain атака през JSON API: как да провериш сайта си

Компрометирана външна JSON емисия засегна седем разширения на BdThemes за WordPress. Атаката не променя нито един файл в хранилището на WordPress.org и не изисква обновяване на разширението, за да зарази сайт – достатъчно е администратор да отвори която и да е страница в wp-admin.

Нападателите са използвали XSS в компонента Biggopti, за да изпълнят JavaScript в сесията на влязъл администратор. После скриптът може да добави нов администратор, да качи разширение с webshell и да инсталира устойчиви задни врати като Must-Use разширения. Всички засегнати разширения временно са затворени в директорията на WordPress до приключване на проверката.

Риск от пълно превземане на сайта

Ако сайтът ти използва някое от изброените разширения, провери го незабавно за индикаторите по-долу. Не разчитай само на проверка за променени файлове: тази кампания работи през отдалечен API и може да не остави промени във файловете на самото разширение.

Засегнати разширения и оценка на риска

Уязвимостта в Biggopti има CVSS оценка 5,4 от 10 – средна тежест – и няма корекция. Тя засяга следните разширения:

Проблемът е Cross-Site Scripting (XSS): Biggopti приема полето display_id от Sigmative API и го добавя в HTML без достатъчно escaping. Всеки, който получи контрол над този API, може да инжектира скрипт, който браузърът изпълнява при отваряне на заразена административна страница.

Как отдалечен банер заразява wp-admin

Biggopti е вътрешен компонент, който показва рекламни банери в таблото на WordPress. Той взема данните от API на BdThemes, зад което стои статичен DigitalOcean Spaces bucket, защитен с Cloudflare. Това не е динамичен приложен сървър, а JSON файлове от object storage.

Всяко разширение, което използва Biggopti, добавя негов JavaScript asset чрез admin_init. Затова кодът се изпълнява безусловно при всяко зареждане на страница в wp-admin, извлича банера от API и сглобява контейнер в Document Object Model (DOM). Уязвимият път директно прави display_id част от HTML атрибута id:

// Стойността идва от отдалечения JSON без escaping.
var f = t.display_id || t.id || "default";
var m = "bdt-admin-biggopti-api-biggopti-" + f;
A = 'id="' + m + '"';

В същия код data-display-id се escape-ва чрез функция, която заменя &, <, >, и двойните кавички с HTML entities. Това показва, че липсата на escaping при id не идва от техническа необходимост. Минифицирането или bundling-ът правят структурата на кода по-трудна за четене, но не премахват проблема.

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

Историята на SVN показва, че Prime Slider 4.1.9 е получил незащитеното вмъкване на 1 март 2026 г., а после то е преминало и към други разширения. По-късните версии добавят sanitizer с DOMParser за полето със съдържанието на банера – той премахва опасни HTML елементи и inline handlers – но атрибутът id остава незащитен.

Нападател с достъп за запис до storage bucket-а е заменил легитимните JSON отговори със зловредни. Манипулираното display_id затваря атрибута id, добавя onanimationstart handler и активира CSS анимация. Събитието се задейства за около 10 милисекунди и стартира кода тихо при всяко отваряне на административна страница.

Към момента на улавяне на артефактите отговорът съдържа поле display_id, което започва с SAFE" onanimationstart=... и декодира JavaScript за изтегляне и изпълнение на външен скрипт от api.sigmative.io. Банерът е маркиран като adminDashboard и носи заглавие „Build more. Pay less. This Summer“.

Какво правят двата payload-а

Инжектираният handler избира външен скрипт според достъпността на инфраструктурата на нападателите. Кампанията използва два различни payload-а и изпраща резултатите от изпълнението към command-and-control (C2) сървър.

Основен payload: w2.js

Основният скрипт се подава към разширенията, които използват endpoint-а api-data-all-records. Той работи в автентикираната сесия на администратора и преминава през следната последователност:

  1. Проверява C2. Свързва се с ia-cdn[.]com/fz/c, изпраща origin на сайта и взема инструкции за таргетиране. Ако C2 върне skip или done, прекратява работата си.
  2. Добавя неоторизиран администратор. Използва X-WP-Nonce от активната администраторска сесия, за да създаде потребител през WordPress REST API. Ако това не успее, подава стандартни формуляри.
  3. Инсталира webshell. Изтегля ZIP, представен като разширение, от C2 и го качва през обичайния формуляр за качване на разширения. Фалшивото разширение използва slug като wp-smart-thumbnails или друго неутрално име и съдържа webshell emer-run.php, който се извиква директно през URL.
  4. Инсталира Must-Use задни врати. При извикване emer-run.php записва два модула в директорията за Must-Use разширения. И двата намерени образеца са с променено време до септември 2025 г., за да изглеждат като легитимни стари файлове; имената могат да се различават между инфекциите. Първият е magic-login заден вход през ?_wplogin=<token>, насочен към администратора с най-ранна регистрация в сайта. Вторият прихваща заявки към базата от данни, скрива създадените акаунти от списъка с потребители и намалява показвания общ брой потребители.
  5. Изнася резултатите. Изпраща статуса на всяка фаза към C2 чрез navigator.sendBeacon.

Алтернативен payload: x.js

Вторият скрипт е бил хостван директно в инфраструктурата на BdThemes и се подава към разширенията, които използват api-data-records. Той генерира предвидими администраторски данни от hostname на жертвата: изчислява 32-битов hash, превръща абсолютната му стойност в base36 и взема първите шест знака.

Потребителското име има вид bd_ плюс шестзнаковия base36 hash, а паролата е Bd@26!, следвана от същия hash и x. Скриптът свързва акаунта с имейл в домейна @wordpress.org. Понеже данните са детерминистични, нападателите не трябва да пазят централен списък със заразените сайтове, а екипът по реакция може да изчисли търсения акаунт за проверяван домейн.

След като генерира тези данни, x.js отваря /wp-admin/user-new.php с credentials same-origin, извлича nonce от HTML и изпраща формуляр за създаване на потребител с роля administrator. Запазва флаг в localStorage, когато това е възможно, за да не повтаря операцията, и изпраща към C2 статуса, потребителското име, паролата, origin-а, URL на logout и URL на текущата страница. Първо използва navigator.sendBeacon, а при неуспех изпраща fetch POST заявка в режим no-cors с keepalive.

Обхват и индикатори за компрометиране

C2 домейнът се свързва със същите нападатели, които стоят зад supply chain атаките срещу Advanced Responsive Video Embedder и OptinMonster през предходните два месеца. Целта е масово и тихо запазване на администраторски достъп и отдалечено изпълнение на код в WordPress среди.

Тук не е нужен първоначален достъп до отделните сайтове. Компрометирането на рекламния feed е достатъчно, за да превърне доверените административни известия в канал за malware. Наличието на зловредните JSON записи и x.js направо в bucket-а на доставчика сочи сериозно компрометиране на cloud credentials или вътрешна инфраструктура на BdThemes.

Потърси следните мрежови индикатори:

  • Основен payload: ia-cdn[.]com/fz/w2.js
  • C2 beacon endpoint: ia-cdn[.]com/fz/c
  • Компрометирани API endpoint-и, които вече връщат чист JSON: api[.]sigmative[.]io/prod/store/api/biggopti/api-data-all-records, api[.]sigmative[.]io/prod/store/api/biggopti/api-data-records и api[.]sigmative[.]io/prod/store/api/biggopti/x.js.

Провери файловата система и базата от данни за следните индикатори:

  • Webshell emer-run.php с MD5 1024732009983dd5e54b4cf5593f04d4.
  • Must-Use magic-login модул class-wp-token-validate.php с MD5 7719cd98a35ffad2771f26d1ceab7d27.
  • Must-Use stealth модул class-wp-query-9d127ff3.php или подобно име от вида class-wp-query-*.php, с MD5 9aadc3e5c5242b273bd17c5bdc358845.
  • Must-Use модул, представен като health check, wp-cache-optimizer.php, с MD5 e450ae5bc4bfc0d960dded06a76bb8e9.
  • Опция в базата от данни fz_emer_login_tokens, която пази magic-login токени.
  • Опция в базата от данни fz_emer_done_v1, която отбелязва завършено компрометиране.
  • Акаунти с имейл в @wordpress.org или @developer.wordpress.org.
  • Потребителски имена от вида bd_ и шест буквено-цифрови знака след префикса.

Времева линия

  • 1 март 2026 г. – Biggopti API JavaScript влиза в Prime Slider 4.1.9 чрез SVN r3471891. display_id се добавя без escaping към атрибут id, а API endpoint-ът е api-data-records.
  • 10 май 2026 г. – endpoint-ът се сменя с api-data-all-records. Добавя се DOMParser sanitizer за полето със съдържание, но id остава незащитен.
  • 23 юни 2026 г.start_date в компрометираната API кампания посочва „Summer Sale“ известие. Това е най-ранната възможна дата, на която XSS може да е бил активен.
  • 6 август 2026 г., 22:40 UTC – последната промяна на компрометирания api-data-records.
  • 7 август 2026 г., 09:11 UTC – последната промяна на компрометирания api-data-all-records.
  • 7 август 2026 г. – атаката е наблюдавана в реална среда и засегнатите разширения са затворени в директорията на WordPress до проверка.
  • 7 август 2026 г., 16:56 UTC – запазени са артефакти от разследването.
  • 8 август 2026 г. – и двата API endpoint-а вече връщат чист JSON.

Какво да направиш сега

Провери потребителите в базата от данни и в таблото, но не приемай списъка в wp-admin за достатъчен: stealth модулът може да скрие акаунт и да промени броя потребители. Търси директно в таблицата с потребители за посочените имейл домейни и потребителския шаблон bd_ плюс шест знака.

Прегледай директорията за разширения, директорията за Must-Use разширения и таблицата с опции за всички IoC. Провери web access и DNS логове за връзки към ia-cdn[.]com, както и дали няма директни заявки към emer-run.php. Ако откриеш какъвто и да е индикатор, третирай инсталацията като напълно компрометирана: премахни зловредните акаунти и файлове, прекрати активните сесии, смени администраторските пароли и всички тайни, до които сайтът може да е имал достъп.

Премахни или изолирай засегнатите разширения, докато няма потвърдена корекция, и провери бекъпите, преди да възстановяваш от тях. Само файлов integrity scan няма да хване първоначалната атака, защото тя идва от доверен отдалечен JSON отговор, а не от редактиран файл на диска.

Засичане

Правилата за WAF и сигнатурите за тази кампания са налични от 7 август 2026 г. за Wordfence Premium, Care, Response и платения Wordfence CLI. Безплатните потребители на Wordfence и Wordfence CLI ще ги получат след стандартно забавяне от 30 дни.

След инцидента добави проверка на външните ресурси, които разширенията зареждат в административната зона, към процеса си за security review. Supply chain рискът не свършва с подписания ZIP пакет: API отговор, CDN asset или статичен storage bucket също може да изпълни код в доверения браузърен контекст на администратора.

Мария Иванова

Мария Иванова

Главен редактор на българския екип, разработчик на AI и машинно обучение. PyTorch и обработката на естествен език са моите основни области. Бъдещето вече е тук.

Всички публикации

Присъединете се към общността на HelloWP!

Разговаряйте с нас за WordPress и уеб разработка и споделяйте опит с други разработчици.

- членове
- онлайн
Присъединяване

Използваме бисквитки, за да подобрим вашето изживяване. Продължавайки, вие се съгласявате с нашата Политика за бисквитки.