Сразу оговоримся: неуязвимых сайтов не бывает. У Next.js была своя критическая дыра, мы о ней расскажем. Вопрос не в том, можно ли взломать сайт, а в том, сколько у него дверей, кто ещё стоит у тех же дверей и как быстро их закрывают.
Как устроена массовая атака
Массовые взломы держатся на одинаковости. Готовый движок, популярный шаблон или плагин стоит на тысячах сайтов. Когда в нём находят дыру, программа взломщика проверяет миллионы адресов и заходит туда, где её не закрыли. Сайт не выбирают — его находят.
У готовых движков к тому же много авторов. Сам движок пишет одна команда, а шаблоны и плагины — сотни других, с разным отношением к безопасности. Сайт на WordPress или Joomla с двадцатью расширениями — это двадцать разных поставщиков кода. Обновлять каждое расширение нужно отдельно, и именно об этом чаще всего забывают.
Именно так случились две истории этой осени:
- Helix3 — основа для шаблонов Joomla. Дыру закрыли 29 июня, массовые взломы начались около 5 июля. В ноябре мы начали лечить два сайта клиента, взломанных именно так.
- PHP2Shell — две дыры в самом PHP, на котором работают WordPress, 1С-Битрикс и Joomla. Исправление вышло 21 октября, из-за этих дыр в Европе отключали госсайты. Как мы проверяли интернет-магазин.
Чем сайт на Next.js устроен иначе
Next.js — это инструмент, на котором собирают сайты на JavaScript. На нём мы делаем свои проекты: этот сайт, сайты для ПЭТ Индустрии, Le Fabric, Студии Ю.
Главное отличие — в том, что происходит, когда посетитель открывает страницу.
Сайт на готовом движке при каждом открытии страницы запускает программу на сервере: она читает базу данных, подключает шаблон и плагины, собирает страницу. Каждый запрос посетителя проходит через весь этот код. Значит, каждая дыра в любом его кусочке доступна любому, кто пришлёт запрос.
Сайт на Next.js может работать двумя способами. В первом страницы собираются заранее, при выпуске сайта, и сервер просто отдаёт готовые файлы — как картинки. Программы, которую можно атаковать запросом, на сервере нет вовсе. Так работает, например, этот сайт. Во втором способе сервер собирает страницы на лету, но это один небольшой код, написанный под проект, а не движок с десятками расширений от разных авторов.
| Готовый движок на PHP | Сайт на Next.js | |
|---|---|---|
| Что выполняется при открытии страницы | Движок, шаблон и все плагины | Ничего (готовые страницы) или код проекта |
| Сколько сторонних авторов в коде, который видит посетитель | Движок плюс автор каждого шаблона и плагина | Фреймворк и библиотеки, без плагинов «из магазина» |
| Где админка | На том же сайте, по известному адресу | Отдельно от сайта или её нет совсем |
| Как ставят обновление | Каждое расширение отдельно, часто вручную | Сборка и выпуск сайта целиком |
| Что ломают массовые атаки | Известные дыры в движке, шаблонах, плагинах и PHP | Дыры во фреймворке, если сайт работает с сервером |
Админка — отдельная тема. На готовом движке она находится по известному адресу на том же сайте, и роботы годами перебирают к ней пароли. На сайте, который собран заранее, админки на сервере нет. Если клиенту нужно управлять содержимым, мы ставим отдельную систему управления — например, Directus в проекте для ПЭТ Индустрии, а не плагин внутри публичного сайта.
Слабые места сайтов на Next.js
Было бы нечестно на этом остановиться. Next.js тоже стоит на огромном числе сайтов, и с ним случалось то же, что с готовыми движками.
React2Shell. 3 декабря 2025 года разработчики сообщили о критической уязвимости с максимальной оценкой опасности 10 из 10. Она позволяла выполнить свой код на сервере сайтов на Next.js 15 и 16, которые собирают страницы на лету с новой схемой маршрутов (App Router). Временного обхода не было — только обновление. Сайты, которые отдают заранее собранные страницы, это не затрагивало: на их сервере нет кода Next.js. Все наши действующие проекты собраны на Next.js 16.1 и новее, то есть на версиях, вышедших уже с исправлением.
Заражённые библиотеки. Сайт на JavaScript собирают из сотен небольших библиотек. В сентябре 2025 года взломщики захватили учётную запись автора популярных библиотек и выпустили их заражённые версии. Защита — фиксировать точные версии библиотек и не обновлять их вслепую в день выхода.
Формы и обработчики. Готовые страницы ничего не принимают, а форма заявки должна куда-то отправлять данные. Обработчик формы — это код на сервере, и его нужно защищать как любой код: проверять данные, ограничивать частоту запросов. Если сайт живёт на обычном хостинге, обработчик формы там часто пишут на PHP, и тогда PHP2Shell касается и его. Версию PHP для такого обработчика нужно проверять так же, как для любого сайта на PHP.
Хостинг, домен и пароли. Никакая технология не защитит от слабого пароля к панели хостинга или от утёкшего доступа к почте, на которую зарегистрирован домен. Двухфакторный вход нужен везде.
Как мы защищаем сайты, которые делаем
- Собираем страницы заранее, где это возможно. Этот сайт целиком отдаётся готовыми файлами. Заявки с форм принимает отдельная небольшая программа, которая больше ничего не умеет.
- Админку отделяем от сайта. Если нужно управление содержимым, это отдельная система, а не часть публичного сайта.
- Фиксируем версии библиотек. Сборка повторяется из одного и того же списка; обновление — осознанное действие, а не случайность.
- Ставим защитные заголовки. Они запрещают браузеру встраивать сайт в чужие страницы, угадывать тип файлов и открывать сайт без шифрования. На проекте для Студии Ю это шесть заголовков, включая политику источников содержимого (CSP).
- Обновляем по новости, а не по расписанию. Когда выходит исправление, нужно понять, касается ли оно сайта, и выпустить обновление. Это часть сопровождения.
Когда переезжать с готового движка, а когда нет
Готовый движок — не приговор. 1С-Битрикс, WordPress и Joomla прекрасно работают, если их обновляют вместе с расширениями и PHP, и за сайтом кто-то следит. Мы сами сопровождаем магазин на 1С-Битрикс.
Переезд оправдан, если:
- версия движка больше не получает исправлений, как Joomla 3 с августа 2023 года, а обновить её без переделки шаблона нельзя;
- сайт держится на старом PHP, и переход на новую версию ломает его;
- сайт уже взламывали, и в нём столько чужого и забытого, что проще собрать заново;
- сайт и так пора переделывать — по дизайну, скорости или удобству.
Переезд не нужен, если движок поддерживается, обновления ставятся, а сайт решает задачи бизнеса. Тогда дешевле наладить сопровождение. Что делать, если сайт уже взломан, — в пошаговом разборе.
Для технических специалистов
Режимы Next.js и поверхность атаки
При output: "export" Next.js выдаёт статические файлы, которые отдаёт nginx: на сервере нет Node.js-процесса и обработчиков React Server Components. При output: "standalone" работает сервер Node.js, и к нему относятся уязвимости рантайма. Этот сайт собран в режиме export на Next.js 16.1.6 и React 19.2.3; приём заявок /api/lead проксируется nginx на отдельный сервис на 127.0.0.1.
React2Shell
CVE-2025-55182 в React, для Next.js — CVE-2025-66478 (позже отклонён как дубликат). CVSS 10.0. Затронуты приложения с React Server Components на App Router: Next.js 15.x, 16.x и канареечные сборки начиная с 14.3.0-canary.77. Не затронуты Next.js 13.x, стабильная 14.x, Pages Router и Edge Runtime. Исправлены 15.0.5, 15.1.9, 15.2.6, 15.3.6, 15.4.8, 15.5.7, 16.0.7. Разработчики рекомендовали после обновления сменить все секреты приложения, если оно было в сети без исправления на 4 декабря 2025 года.
Цепочка поставки
Что помогает: точные версии в package-lock.json, установка через npm ci, а не npm install, аудит зависимостей перед выпуском и пауза перед установкой только что вышедших версий. Заражённые версии chalk и debug в сентябре 2025 года продержались в реестре считаные часы — пауза в несколько дней их бы отсекла.
Заголовки
На этом сайте: Strict-Transport-Security: max-age=31536000; includeSubDomains, X-Frame-Options: SAMEORIGIN, X-Content-Type-Options: nosniff, Referrer-Policy: strict-origin-when-cross-origin, Permissions-Policy: camera=(), microphone=(), geolocation=().
Вопросы и ответы
Сайт на Next.js нельзя взломать?
Можно, как и любой другой. Но у него меньше дверей: нет движка с плагинами от разных авторов, нет админки на том же адресе, а в режиме готовых страниц нет и программы на сервере. Массовые атаки на готовые движки и PHP его не касаются.
Что такое статический сайт?
Сайт, страницы которого собраны заранее и лежат на сервере готовыми файлами. Сервер ничего не вычисляет, а просто отдаёт их. Такой сайт быстро открывается и почти не даёт поверхности для атаки. Next.js умеет собирать сайты так, при этом сохраняя формы, анимацию и интерактивные элементы.
Можно ли управлять содержимым статического сайта самому?
Да. Для этого ставят отдельную систему управления, где редактируют тексты и товары, а сайт пересобирается после изменений. Публичная часть при этом остаётся набором готовых файлов.
1С-Битрикс небезопасен?
Нет. Это зрелая система с собственной командой безопасности. Опасен любой движок, который не обновляют. Битрикс, за которым следят, обычно надёжнее сайта на любой технологии, за которым не следит никто.
Стоит ли переделывать сайт после взлома?
Сначала его нужно вылечить. Переделывать стоит, если движок больше не поддерживается или сайт и так пора менять. Иначе дешевле обновить и наладить сопровождение.