Скимминг на Magento: 953 магазина с лоадером в CMS-блоках

Безопасность

Скимминг на Magento: 953 магазина с лоадером в CMS-блоках

Скимминг на Magento: JS-лоадер в CMS-блоках 953 интернет-магазинов прячется от сканеров безопасности

Нидерландская компания Sansec нашла скрытый JavaScript-лоадер в CMS-блоках 953 интернет-магазинов, большинство из них работают на Magento. Это готовая инфраструктура для скимминга на Magento, и вредоносный скрипт она отдаёт только живым покупателям, поэтому сканеры безопасности месяцами видят чистую витрину.

Коротко

  • Sansec нашла JS-лоадер в CMS-блоках 953 интернет-магазинов, большинство — на Magento; кампания идёт с июля 2025 года и сменила пять доменов.
  • Код живёт в таблице cms_block, поэтому проверка файлов и деплоя его не замечает, а сервер злоумышленников не отдаёт скрипт сканерам.
  • Основные точки входа — PolyShell (CVE-2026-48356) и SessionReaper (CVE-2025-54236), но один полностью обновлённый магазин заразили через посторонний аккаунт администратора.
  • При реагировании важен порядок: сохранить доказательства, удалить веб-шеллы и чужих админов, и только затем менять пароли и ключи.
  • Финальная нагрузка неизвестна, но по PCI DSS v4.0 скрипты на платёжных страницах уже должны быть под контролем.

Кампания с июля 2025 года: 953 магазина и неизвестная группа

Sansec описала одну долгоиграющую кампанию. С июля 2025 года неизвестная группировка заразила 953 интернет-магазина, большинство из них работают на Magento (Adobe Commerce). Пересказ отчёта опубликовал Ravie Lakshmanan в The Hacker News 26 октября 2026 года. Имени у группы нет: Sansec называет её просто неизвестным злоумышленником.

Схема типична для Magecart-атак: на страницу магазина подсаживают фрагмент кода. Когда покупатель открывает витрину, браузер загружает скрипт с сервера злоумышленников и выполняет его. Код внутри доверенной страницы видит всё, что видит покупатель, в том числе поля формы оплаты.

Оговорка: что за финальная нагрузка, Sansec выяснить не смогла. JavaScript в контексте страницы технически способен читать поля формы и перехватывать ввод до отправки на сервер. Но факт кражи карт в этой кампании пока не доказан, поэтому корректнее говорить о скимминговой инфраструктуре, а не о подтверждённой краже платёжных данных.

И о масштабе: 953 — это число площадок, а не покупателей и не украденных карт. Сколько людей прошли через заражённые витрины, неизвестно, так что сравнивать эту цифру с числом пострадавших в других утечках некорректно.

Открытых вопросов в этой истории больше, чем ответов:

  • что именно получают покупатели на финальной стадии: скиммер карт, редирект или что-то третье;
  • кто стоит за кампанией;
  • как появился посторонний администратор в полностью обновлённом магазине;
  • правят ли злоумышленники существующие блоки или создают новые — новый блок легко заметить в списке, а вставка в давно живущий футер теряется среди счётчиков, чатов и пикселей аналитики;
  • сколько покупателей прошли через заражённые витрины.

Как JS-лоадер попадает на витрину через CMS-блоки

Злоумышленники прячут лоадер в базе данных Magento, в таблице cms_block, а не в файлах темы. Эта таблица хранит статический контент, который движок вставляет в страницы: шапку, подвал, промо-баннер, плашку с условиями доставки. Покупатель открывает сайт, блок рендерится вместе с витриной и запускает загрузку внешнего скрипта.

Проверка целостности файлов, git diff и сравнение с эталонным релизом здесь ничего не покажут: код ядра и темы никто не трогал. Изменение живёт в строке базы, которую обычно правит маркетолог через админку, а не разработчик через деплой. По той же причине Sansec советует проверять и соседнюю таблицу cms_page.

Инфраструктура раздачи за это время менялась несколько раз. Sansec насчитала пять доменов лоадера, которые впервые появлялись в июле 2025-го, декабре 2025-го, марте, июне и октябре 2026 года. Самый свежий зарегистрировали 6 октября 2026 года, и его уже прописали в CMS-блоки 83 магазинов. Сами адреса мы не публикуем: полный список индикаторов есть в отчёте Sansec.

Новый домен стоит за Cloudflare. Взлом Cloudflare здесь ни при чём: злоумышленникам CDN нужен, чтобы скрыть адрес исходного сервера и получить отказоустойчивость. Блокировать что-то по признаку «стоит за Cloudflare» бессмысленно, искать надо конкретные домены из отчёта.

Для владельцев отсюда следует организационный вывод: изменения CMS-блоков должны проходить хотя бы через журнал и ревью, как код. Мы закладываем такой контроль, когда ведём разработку и доработку магазинов на Magento, и это дешевле любого расследования.

Почему сканер не видит вредоносный скрипт

Сервер злоумышленников сначала решает, кто к нему пришёл, и сканерам не отдаёт ничего. По описанию Sansec, браузер посетителя спрашивает у сервера группы, что делать дальше, а тот сперва проверяет, настоящий это покупатель или сканер безопасности.

В ранних волнах отсев делал сторонний легальный сервис. Злоумышленники приспособили Keitaro, платформу рекламного трекинга и аналитики, под систему распределения трафика (TDS). В зависимости от характеристик посетителя система отдавала нагрузку, перенаправляла его или не отдавала ничего.

Sansec запросила скрипт с июньского домена под видом обычного десктопа на Windows. В ответ пришла пустышка, которая лишь ставила cookie и помечала посетителя на 24 часа.

С октябрьским доменом Keitaro исчез, и логика отсева переехала прямо в лоадер. Меньше внешних зависимостей — меньше следов и меньше поводов сломаться. Пятый домен за 15 месяцев, собственный фильтр вместо стороннего TDS и быстрое переключение блоков на новый адрес говорят о том, что группа активна и вкладывается в незаметность.

Исследователи видели два варианта лоадера:

  • С сохранением в localStorage. Нагрузка оседает в локальном хранилище браузера, которое привязано к домену магазина и переживает перезапуск браузера. При следующих визитах код выполнится снова, даже если внешний домен уже отключили.
  • С отпечатком браузера. Второй вариант добавляет fingerprinting, чтобы отсеять ботов и сканеры. Вредоносный код получает только тот, кто похож на живого человека.

Единичный curl к домену лоадера, запрос с сервера или внешний онлайн-сканер вполне могут вернуть чистый ответ. Ответ может зависеть от Referer, User-Agent, cookie, IP-адреса и числа обращений, так что пустой результат ничего не доказывает.

Автоматическое сканирование и оценка уязвимостей покажет устаревшую версию Magento и незакрытые CVE, но ручную проверку не заменит. Содержимое cms_block придётся читать глазами или сверять с эталоном, а сетевую цепочку восстанавливать по HAR-файлам, логам прокси и сохранённым копиям скриптов.

Откуда у злоумышленников доступ: PolyShell, SessionReaper или чужой админ?

Большинство заражений Sansec связывает с известными уязвимостями Magento, но далеко не все. По оценке компании, 471 магазин, почти половину, заразили через PolyShell (CVE-2026-48356). На ещё 102 витринах злоумышленники загрузили файлы через PolyShell или SessionReaper (CVE-2025-54236). Это оценки, а не криминалистика каждого случая.

Два разобранных случая показывают разницу.

Магазин без патча

Первый работал на Magento 2.4.7-p1 и так и не получил APSB26-73 — исправление Adobe против PolyShell для поддерживаемых веток. В каталоге pub/media/custom_options/quote/ лежали веб-шеллы PolyShell, замаскированные под PNG-картинки, а в CMS-блоке сидел лоадер.

7 октября 2026 года, на следующий день после регистрации свежего домена, блок переключили на новый адрес. Похоже, злоумышленники сохраняли доступ к магазину и возвращались к нему.

Магазин со всеми патчами

Второй стоял на 2.4.7-p10, и патчей ядра у него не пропущено. Злоумышленники завели там собственную учётную запись администратора и через неё вставили лоадер в CMS. Откуда взялся этот админ, Sansec в публикации не раскрывает. В практике таких путей много: украденный пароль сотрудника или подрядчика, перехваченная сессия, бэкдор с прошлого заражения.

Патч закрывает конкретную дыру, но не удаляет то, что через неё уже успели сделать: веб-шеллы, посторонних админов, изменённые блоки. Если обновиться после компрометации, витрина останется заражённой, просто вход сменится с уязвимости на легитимный логин.

Понять, кто реально может зайти в админку и что он там может поменять, помогает тестирование безопасности веб-приложений. Хороший пентест витрины проверяет не только CVE в ядре, но и права ролей, 2FA и доступность админ-панели из интернета.

Чем скимминг на Magento грозит бизнесу, пока финальная нагрузка неизвестна

Главный риск для владельца магазина — платёжные данные и ответственность за них, и даже то, что финальная нагрузка неизвестна, риска не отменяет. Скрипт, который выполняется на странице оформления заказа, видит всё, что вводит покупатель.

Требования к таким скриптам уже записаны в PCI DSS v4.0, в пунктах 6.4.3 и 11.6.1. Первый требует инвентаризировать и авторизовать скрипты на платёжных страницах, второй — обнаруживать несанкционированные изменения этих страниц и HTTP-заголовков. Для пунктов, которые раньше шли как best practice, срок наступил 31 марта 2025 года.

Точный охват зависит от того, как устроен приём платежей у конкретного мерчанта. Но чужой CMS-блок, который тихо тянет внешний скрипт, — ровно тот сценарий, ради которого эти пункты писали.

Похожие случаи обходились дорого. British Airways в 2018 году пострадала от изменённого скрипта на сайте, и в 2020 году британский регулятор ICO оштрафовал авиакомпанию на £20 млн. Ticketmaster за компрометацию через сторонний чат-компонент Inbenta получила от того же ICO штраф £1,25 млн.

Эти случаи не доказывают, что в кампании Sansec крадут карты, но цену вопроса показывают. Для российских магазинов добавляется 152-ФЗ: утечка персональных данных покупателей влечёт обязательное уведомление Роскомнадзора и возможные штрафы.

Руководителю стоит задать команде два вопроса. Кто отвечает за содержимое CMS-блоков? Кто замечает, когда оно меняется? Если честный ответ звучит как «правит маркетинг, никто не смотрит», проблема уже найдена — и она не в коде.

Что проверить владельцу магазина на Magento на этой неделе

Не стоит ждать публикации нагрузки: проверять магазин нужно уже сейчас. Начинать лучше с учёток и контента — патч обязателен, но, как показал случай с 2.4.7-p10, сам по себе заражение не уберёт.

  1. Сверьте список администраторов (таблица admin_user) с реальным штатом и подрядчиками. Повод для расследования — любая незнакомая запись, учётка уволенного сотрудника или админ, недавно созданный без заявки.
  2. Выгрузите cms_block и cms_page и проверьте содержимое на внешние скрипты, обфусцированный JavaScript и незнакомые домены. Сверьте находки с индикаторами из отчёта Sansec.
  3. Проверьте pub/media, в первую очередь pub/media/custom_options/quote/, на исполняемые файлы под видом картинок.
  4. Установите APSB26-73 для своей ветки. Если вы на 2.4.7-p1 или более старой версии, обновление откладывать нельзя.
  5. Включите двухфакторную аутентификацию для админки, требуйте сильные пароли и закройте админ-панель от интернета через VPN или белый список IP.
  6. Настройте оповещения об изменениях CMS-блоков и Content Security Policy для страниц оформления заказа.

Из практики. На разборах заражённых витрин мы чаще всего видим одну ошибку: блок удалили, пароль сменили, а через неделю всё вернулось. Порядок действий важен. Сначала сохраните доказательства: дампы cms_block и cms_page, список admin_user, журналы входов администраторов, подозрительные файлы с временными метками.

Без них не получится установить, как злоумышленники вошли и сколько длилась компрометация. Потом удаляйте веб-шеллы и посторонних админов. И только после этого меняйте пароли, ключи интеграций, API-токены, SSH/SFTP и учётки деплоя. Если сменить пароль раньше, чем удалён бэкдор, злоумышленник просто прочитает новый.

Отдельно про localStorage. Если в вашем случае подтвердился вариант с локальным хранилищем, не сбрасывайте его всем покупателям разом: так вы выкинете людей из сессий и опустошите корзины. Нужна адресная очистка конкретных вредоносных ключей, которые укажет расследование.

Если своей команды на такой разбор нет, его можно поручить подрядчику по защите сайтов: очистка, поиск точки входа, закрытие повторного доступа.

При чём здесь PHP2Shell?

Напрямую — ни при чём. PHP2Shell — две критические уязвимости в PHP, CVE-2026-109618 и CVE-2026-109619, с оценкой CVSS 9.2. Их раскрыли за неделю до публикации The Hacker News, и с тех пор исследователи фиксируют массовые попытки эксплуатации.

Adel Karimi из Perplexity зафиксировал, судя по всему, первые успешные атаки на серверы-ловушки (honeypot). Атакующие через wget, curl или PHP CLI пытались загрузить следующую стадию с удалённого сервера. Артефактов второй стадии на ловушках пока не обнаружили.

Sansec эту пару уязвимостей с 953 магазинами не связывает. Но Magento работает на PHP, поэтому владельцам магазинов есть смысл проверить версию интерпретатора на своих серверах и обновить его: экстренные исправления разработчики PHP уже выпустили.

Частые вопросы

Это точно кража карт или полезная нагрузка ещё неизвестна?

Неизвестна. Что получают покупатели на финальной стадии, Sansec выяснить не смогла. Код на странице оплаты технически способен красть введённые данные, но факт кражи карт в этой кампании пока не доказан.

Сколько доменов лоадера сменила группа?

Пять: они впервые появлялись в июле 2025-го, декабре 2025-го, марте, июне и октябре 2026 года. Самый новый зарегистрировали 6 октября 2026 года, и его уже нашли в CMS-блоках 83 магазинов.

Что такое PolyShell и какой патч Adobe его закрывает?

PolyShell (CVE-2026-48356) — уязвимость Magento, через которую, по оценке Sansec, заразили 471 магазин. В поддерживаемых ветках её закрывает исправление Adobe APSB26-73.

Поможет ли WAF, если код уже лежит в cms_block?

Против уже внедрённого кода почти нет: WAF фильтрует входящие запросы, а лоадер отдаёт сам магазин из своей базы. WAF может помешать первичному входу через уязвимость, но очистку CMS и аудит админов он не заменит.

Почему пропатченный Magento 2.4.7-p10 всё равно оказался заражён?

Злоумышленники завели там собственную учётную запись администратора и через неё вставили лоадер в CMS-блок. Обновления закрывают уязвимости, но не удаляют посторонних админов и уже изменённый контент.

Нужно ли из-за этой новости срочно ставить патчи PHP2Shell?

PHP2Shell (CVE-2026-109618 и CVE-2026-109619, CVSS 9.2) с кампанией против 953 магазинов не связан. Обновить PHP всё равно стоит: попытки эксплуатации массовые, а Magento работает на этом интерпретаторе.

Если нашли в CMS-блоках или списке администраторов что-то чужое, команда HirexTech возьмёт на себя защиту сайта от взлома: очистит витрину, найдёт точку входа и поможет выстроить контроль изменений без лишней бюрократии.

Прокрутить вверх