25 октября 2026 я проверил семь своих Next.js-сайтов, которые сам хостю, и шесть из них оказались уязвимыми. Портфолио, которое вы читаете, стояло на 16.2.10. Причина: уязвимость Next.js, которую команда закрыла внеплановым релизом 14 октября. Две критические уязвимости удалённого выполнения кода (RCE) и один отказ в обслуживании.
Дальше: какие версии затронуты, как проверить свою за пару минут, что я поменял и что оставил как есть. По Instagram и LinkedIn ходит ролик про безопасность с 15 идентификаторами, и одна подпись в нём неверна. Для обновления это важно, поэтому начну с неё.
Уязвимость Next.js от 14 октября: что исправили#
Источник: официальное обновление безопасности Next.js от 14 октября 2026 и связанные бюллетени GitHub. Исправленные версии: 16.4.1 и 15.5.28. На 25 октября последняя в npm: 16.4.3.
| ID | Что | Кого касается | Исправлено в |
|---|---|---|---|
| GHSA-673q-mjm6-r5xr (CVE пока нет), CVSS v4 9.5 | RCE без аутентификации в функциях use cache, возвращающих типизированные массивы | 16.0.0–16.4.0, App Router с Cache Components и функцией use cache, возвращающей несколько типизированных массивов | 16.4.1 (15.x в списке нет) |
| GHSA-2464-fhr4-w9xw, upstream CVE-2026-96889, CVSS v4 9.5 | RCE без аутентификации в Image Optimization API при обработке SVG | 10.0.0–15.5.27 и 16.0.0–16.4.0, на Linux с glibc | 15.5.28 и 16.4.1 |
| GHSA-p3m5-59mp-jv5r, CVE-2026-94482, CVSS v4 8.2 | Отказ в обслуживании в App Router с Server Actions | 13.0.0–15.5.27 и 16.0.0–16.4.0, если есть хотя бы один Server Action | 15.5.28 и 16.4.1 |
Приложения на Pages Router без Server Actions третьей уязвимости не подвержены. Для первой и третьей обходных путей нет. По первой Vercel советует обновляться, даже если такой функции у вас нет. Так я и сделал.
CVE-2026-96889 не относится к Next.js#
В ролике это «Next.js CVE-2026-96889». В записи написано другое: это use-after-free в librsvg («xml includes have duplicated entities»), опубликована 23 сентября, CNA — Red Hat, CVSS v3.1 7.8. В Next.js она попадает через sharp, который рисует SVG через librsvg. Бюллетень по sharp: GHSA-wq5f-xc86-pv6w, затронуты версии ниже 0.35.5.
Почему подпись важна? Потому что от неё зависит лечение. Одна мера: обновить next. Вторая: убедиться, что sharp не ниже 0.35.5. И тут ловушка: next@16.4.3 зависит от sharp ^0.35.5, а next@15.5.28 допускает ^0.34.3 || ^0.35.5. На 15.x после обновления lockfile спокойно оставит sharp 0.34.x. У меня так и было, поэтому sharp я теперь закрепляю явно.
Ещё два факта, пока вы не запаниковали. Ни один из 15 идентификаторов из ролика не входит в каталог CISA KEV (сверял с версией от 23 октября), а оценка CISA ADP по эксплуатации везде «none», кроме этой уязвимости: у неё «poc». «Чёрный октябрь» — не именованная кампания, а набор настоящих бюллетеней безопасности (nginx, Next.js, GitLab, PHP, Node.js, Java), вышедших в пределах двух недель. Остальной список разобран в обзоре CVE октября 2026.
Как проверить версию Next.js и свою уязвимость#
Тому, что здесь показывает браузер, я не верю. Смотрите lockfile и работающий контейнер:
npm ls next sharp # pnpm: pnpm why next
npm view next dist-tags # что сейчас актуально в npm
npm audit --omit=dev # pnpm: pnpm audit --prod
docker run --rm <image> node -v # версия Node внутри образаПотом три grep, чтобы понять, какой бюллетень реально про вас:
grep -rn "use cache" app src # первая уязвимость RCE
grep -rn "use server" app src # DoS через Server Actions
grep -n dangerouslyAllowSVG next.config.* # путь через SVGНет use cache: первая дыра до вас не дотянется, но обновиться всё равно стоит. Нет "use server": DoS вам не грозит. А dangerouslyAllowSVG: true в конфиге — то, на что я бы смотрел внимательнее всего.
Как обновить: Next.js, sharp, zod, Node в Docker#
Что я делал, по порядку:
npm install next@16.4.3 # если у вас 16.x
npm install next@15.5.28 # если у вас 15.x
npm install sharp@^0.35.5 # явное закрепление- Next.js. 16.x до 16.4.3, 15.x до 15.5.28. Если вы пропускали сентябрьские обновления, вспомните прежние бюллетени: RCE на серверах под Windows (CVE-2026-75604, исправлено в 15.5.24 и 16.3.3), RCE в Image Optimization с AVIF (те же версии) и RCE в
next/ogImageResponse (CVE-2026-94545, исправлено в 16.3.6). Прыжок сразу на актуальные версии закрывает все. - sharp. Закрепите
^0.35.5по причине выше. Прежние бюллетени по sharp (libvips в GHSA-f88m-g3jw-g9cj, libheif в GHSA-rgj7-g3m4-5g8c) этим же закрепом покрываются. - zod. Раз уж я был в lockfile, поднял zod 4.x до 4.6.6 и выше: GHSA-mrhx-c7xc-m3w5, исчерпание памяти на слишком больших ограниченных коллекциях.
- Node в Docker. 21 октября вышли Node.js 22.23.4, 24.22.1 и 26.12.1 (официальный пост), в них четыре high: запись за границы в декодере Brotli, обрезание имён по NUL-символу в
dns.resolve*и два обхода проверки имени хоста в TLS. Работающий контейнер сам не обновится, образ нужно пересобрать. - SVG. Если через
next/imageу вас не проходит ни один SVG, вернитеimages.dangerouslyAllowSVGвfalse.
С Docker я споткнулся дважды. Базовый образ портфолио был закреплён по digest на старой сборке node:22. Пин замораживает всё, включая патчи безопасности, а процесса ротации у меня не было. Другой сайт до сих пор работал на node:20: он снят с поддержки с апреля 2026 и исправлений не получает вовсе. Плавающий node:22-slim тоже не спасает: образ может прийти из кэша сборочного хоста, и пересборка не подтянет свежий патч. Надёжный вариант — явный тег из зеркала AWS:
FROM public.ecr.aws/docker/library/node:22.23.4-slim AS baseВариант (slim, alpine) берите тот, что у вас уже есть. После сборки docker run --rm <image> node -v должен вывести v22.23.4. Та же логика работает для всего, что вы хостите сами; про это я писал в заметке о самохостинге ClewWiki.
Что нашлось на моих семи сайтах#
Мой стенд: семь Next.js-сайтов в Docker на одном сервере, выкатка через Dokploy, спереди Traefik. nginx, PHP, Java и GitLab на сервере нет, поэтому большая часть октябрьского списка меня не касалась.
| Проверка | Результат на 25 октября |
|---|---|
| Уязвимы при аудите | 6 из 7 |
| Найденные версии | 16.2.10 (портфолио), 16.3.8, 15.5.21, 15.5.22, 15.5.23, 15.5.25; один уже на 15.5.28 |
npm audit --omit=dev на портфолио | 12 проблем: 2 critical (next, dompurify), 8 high. После обновления critical: 0 |
use cache в коде | ни на одном из 7 сайтов |
| Server Actions | на одном сайте, значит DoS там был применим |
| Базовые образы Docker | один закреплён digest на старом node:22, один на node:20; все переведены на node:22.23.4-* |
Больше всего мне не нравится находка в next.config.js портфолио. Там стояло images.dangerouslyAllowSVG: true с песочницей в CSP, а за всё время ни один SVG через next/image не проходил. Открытая дорога именно к SVG-уязвимости при нулевой пользе. Выключил.
Что осталось#
После обновления остальные high в npm audit относятся только к сборке: цепочка workbox и next-pwa и postcss внутри next. Они работают только пока собирается Docker-образ, а не в серверном процессе, так что в рантайме у атакующего к ним нет пути. Я оставил их до следующего цикла зависимостей и пишу об этом прямо, не изображая чистый отчёт. Ещё один честный пробел: само портфолио сидит на zod 3, а исправление zod есть только в 4.6.6. Две его схемы проверяют короткие строки с ограничением длины, а не коллекции, так что багу с памятью там не за что зацепиться; переход на zod 4 записан в список дел. Пути RCE из этого набора закрыты на всех семи.
Всё за пределами моего стека я не трогал. У nginx 1.30.6 и 1.31.7, PHP 8.5.12 с соседними ветками, GitLab и Java свои исправления, детали в обзоре, ссылка на который выше.
Чек-лист#
npm ls next sharpпоказывает next 16.4.1+ (актуальная 16.4.3) или 15.5.28 и sharp 0.35.5 или новее.- В
npm audit --omit=devнет critical. dangerouslyAllowSVGвыключен, если вы не отдаёте SVG черезnext/image.- zod 4.6.6 или новее.
- В Dockerfile явный тег
node:22.23.4-*, а не старый digest и неnode:20. - Образ пересобран,
node -vвнутри совпадает. - После выкатки трафик отдаёт именно новая сборка, а не закэшированная.
Если у вас десять минут, сделайте пункты 1, 3 и 5. Они закрывают две критические уязвимости удалённого выполнения кода и тот патч, который заморозил мой собственный пин.



