Патч вышел. Во вторник, 3 ноября 2026 года Vercel выпустил плановый security-апдейт Next.js как v16.4.5 на линейке Active LTS и v15.5.29 на линейке Maintenance LTS.[1] Релиз закрывает семь адвизори - одно высокой и шесть средней severity - и на этот раз детали полностью публичны: идентификаторы GHSA, affected-версии, условия эксплуатации и рекомендации по каждой проблеме.[1] Ждать больше нечего. Если вы крутите Next.js на своём сервере, ваша часть начинается сейчас.
Если вы на Vercel, пропатченная версия уже раскатывается по их инфраструктуре, и от вас, скорее всего, ничего не требуется, кроме как не блокировать деплой. Если вы self-hostite на VPS, пропатченный код - это то, что зафиксировано в свежесобранной папке .next/standalone, - и до ваших пользователей он не дойдёт, пока вы не обновите зависимость, не пересоберёте артефакт и не перезапустите работающий процесс. Именно эта асимметрия - причина, по которой существует этот гайд.
Что содержит релиз
3 ноября вышло две версии:[1]
- v16.4.5 (Active LTS) - закрывает все семь адвизори этой пачки.[1][2]
- v15.5.29 (Maintenance LTS) - закрывает три из семи.[3] Остальные четыре живут в фичах Cache Components /
use cache, которые есть только на линейке 16.x, поэтому в 15.x их нет вообще.
Команды установки, которые публикует Vercel, буквальные и зафиксированы по версиям:[1]
npm install next@16.4.5 # линейка 16.x Active LTS
npm install next@15.5.29 # линейка 15.x Maintenance LTS
Не путайте это с ситуацией прошлой недели. До 3 ноября в открытом доступе не было ни идентификаторов CVE, ни диапазонов affected-версий, и любой «список CVE», выложенный раньше релиза, был догадкой.[1] Теперь адвизори живут на GitHub, у каждого свой идентификатор GHSA, диапазон affected-версий, CVSS-оценка и детали эксплуатации.[4][5][6][7][8][9][10] Обновляйтесь по ним, а не по слухам.
Семь адвизори одним взглядом
Все семь закрыты в v16.4.5; v15.5.29 покрывает три, отмеченные звёздочкой.[1][2][3]
| Severity | GHSA | Поверхность | Что делает атакующий | Affected-конфигурация |
|---|---|---|---|---|
| High | GHSA-mfr8-8qww-v76h | Cache Components (unstable_cache вместе с use cache) - раскрытие между тенантами |
Во время холодного заполнения кеша параллельный вызов через unstable_cache получает чужой результат без проверки root-параметра, а затем отдаёт его поздним вызывающим того же ключа |
Cache Components включены; публичная функция use cache, читающая root-параметр (например, ID тенанта) и вызываемая также через unstable_cache; affected >= 16.3.0[4] |
| Medium | GHSA-vc7v-qv4w-wrv8 | Cache Components - вложенные use cache (раскрытие между root-параметрами) |
Зависимости root-параметра внутренней записи фиксируются с опозданием, поэтому внешняя запись сохраняется под ключом без root-параметра и переиспользуется для значений тенант/сайт/локаль | Вложенные публичные use cache, где внутренняя функция читает root-параметр и возвращает раннее значение вместе с более медленным async-значением; affected 16.2.0 - 16.4.2[5] |
| Medium | GHSA-rhh4-g77r-r9qj | Cache Components - use cache с бинарными аргументами (раскрытие/отравление между пользователями) |
Разные бинарные аргументы (например, Uint8Array, Blob) дают одинаковый идентификатор кеша, поэтому чужой кешированный результат может уйти другому пользователю | Функции use cache, принимающие security-значимые бинарные аргументы и разделяющие записи между вызывающими; affected 16.0.0 - 16.4.2[6] |
| Medium | GHSA-vvgp-ww4w-46vf | Self-hosted Cache Components - отравление общего shell-кеша | Один неавторизованный crafted GET кладёт значения из запроса в fallback-shell, общий для целого семейства роутов, что даёт персистентные 404 или неверный SSR-контент | Self-hosted next start с включёнными Cache Components и Partial Prefetching unset/false; affected >= 16.4.0[7] |
| Medium * | GHSA-pc58-hwjq-p385 | Self-hosted проброс ответа - устаревший сжатый framing | Контролируемый атакующим fetched Response пробрасывается без изменений, утекая байты декомпрессированного тела с исходным сжатым framing; за HTTP/1.1-прокси, который ставит pipelined-запросы в очередь, ответы могут уйти не тем клиентам |
Приложение возвращает контролируемый атакующим fetched Response без изменений за HTTP/1.1 reverse-proxy с общей backend-коннекцией; срабатывает не при любом проксировании[8] |
| Medium * | GHSA-f3mh-rxg3-f5g2 | Edge-роуты - утечка cookie | Сериализованная cookie, выставленная через NextResponse.cookies.set(), попадает во внутренний заголовок x-middleware-set-cookie, который same-origin JavaScript может прочитать даже для HttpOnly-кук |
Edge Route Handlers / Edge API-роуты, выставляющие cookie через NextResponse.cookies.set(); Node-рантайм-роуты и cookies().set() не затронуты[9] |
| Medium * | GHSA-7qx7-33qx-rqx2 | Image Optimization - обход запрета SVG | Изображение из разрешённого источника классифицируется как AVIF, обходя images.dangerouslyAllowSVG: false, и бэкенд декодирует исходные байты как SVG |
Нативный image-бэкенд, умеющий декодировать SVG; allowlist источников изображений продолжает действовать[10] |
(*) Также закрыто в v15.5.29.[3]
Метки severity приведены по анонсу релиза.[1] Стоит знать одну особенность, если сверяетесь со страницами адвизори на GitHub: в записях GitHub уязвимость GHSA-mfr8-8qww-v76h оценена как moderate по шкале CVSS v4, тогда как в посте релиза Vercel классифицирует её как high.[1][4] Оба - первичные источники; здесь мы воспроизводим маркировку из поста релиза, и практический вывод одинаков в любом случае - если у вас Cache Components на 16.x, ставьте это обновление в приоритет.
Детальный разбор для self-hosted
Четыре из семи адвизори важнее всего тем, кто читает сайт про VPS-хостинг, потому что они описывают форму именно self-hosted-развёртывания, а не поведение на Vercel. Три помечены как self-hosted прямо в названии, а high-находка про раскрытие кеша между тенантами применима к любому self-hosted-приложению с Cache Components.[4][7][8][9]
Отравление общего shell-кеша (next start + Cache Components). GHSA-vvgp-ww4w-46vf - та, что прямо целится в self-hosters, и её условия срабатывания выглядят ровно как рабочий прод: next start, Cache Components включены, Partial Prefetching unset или off.[7] Crafted URL может положить значения route-параметров из запроса в fallback-shell, который шарит целое семейство роутов. Практический ущерб - либо персистентный 404, отдаваемый каждому URL под отравленным shell-ключом, либо SSR-HTML, подставляющий значение параметра атакующего вместо значения посетителя (JS-клиент исправляет его на гидрции; инжекции разметки или скриптов нет, утечки данных нет).[7] Быстрый workaround, если не можете обновиться сразу, - выставить partialPrefetching: true в next.config.[7] Постоянный фикс - поднятие версии.
Инжекция ответа между клиентами за HTTP/1.1-прокси. GHSA-pc58-hwjq-p385 лежит ровно на границе того стека, вокруг которого построен этот сайт: приложение возвращает контролируемый атакующим fetched Response без изменений, а спереди nginx терминирует TLS и проксирует через общую backend-коннекцию.[8] Если такой прокси ставит pipelined-запросы в очередь на одной коннекции, рассинхрон сжатого framing может присвоить ответ не тому клиенту, и атакующий, способный выстраивать запросы на этой коннекции, может впрыснуть ответ другому клиенту или прочитать чужой ответ.[8] Важно: это условная проблема - она требует, чтобы приложение пробрасывало контролируемый атакующим ответ, и требует прокси, который ставит pipelined-запросы в очередь; срабатывает она не при любом расположении прокси.[8] Проверьте, не возвращают ли ваши route-хендлеры fetched-ответы дословно, и учтите, что чистый фикс в v16.4.5 или v15.5.29 убирает класс бага независимо от поведения вашего прокси.
Утечка cookie на Edge-роутах. GHSA-f3mh-rxg3-f5g2 затрагивает App Router Edge Route Handlers и Pages Router Edge API-роуты, которые выставляют cookie через NextResponse.cookies.set().[9] Такие роуты кладут cookie во внутренний заголовок ответа x-middleware-set-cookie, а он, в отличие от Set-Cookie, читается same-origin JavaScript - так что даже cookie с меткой HttpOnly можно прочитать.[9] Для эксплуатации нужна чувствительная cookie на затронутом ответе плюс JS атакующего на том же origin, и баг не касается Node.js route-хендлеров и cookies().set().[9] Если у приложения с авторизацией есть Edge-рантайм-роуты, проверьте, не они ли выставляют cookie, затем обновляйтесь.
Раскрытие кеша между тенантами. GHSA-mfr8-8qww-v76h - high-находка, и она напрямую релевантна любому self-hosted-приложению с Cache Components, которое делит данные по root-параметру - как правило, ID тенанта в мультитенантном деплое.[1][4] В гонке холодного заполнения вызов через unstable_cache может забрать результат параллельного прямого вызова без проверки root-параметра, закешировать его под ключом без скоупа по тенанту и отдавать поздним вызывающим.[4] Идентификатор тенанта - ровно то значение, которое эта схема должна защищать, поэтому мультитенантное 16.x-приложение с Cache Components - самый приоритетный апгрейд всей пачки.
Затронуты ли вы?
Если у вас стоит любая 16.x-версия старше v16.4.5 и вы используете любую из этих фич - Cache Components, use cache, Edge-рантайм-роуты, выставляющие cookie, или image-оптимизацию на нативном бэкенде - считайте себя в зоне поражения и обновляйтесь.[1][2][4][5][6][7] Конкретные диапазоны affected-версий из адвизори (например, >= 16.3.0 для high-находки, 16.0.0 - 16.4.2 для бинарных аргументов) стоит прочитать на отдельных страницах адвизори, потому что часть веток уже была закрыта в 16.4.2.[4][5][6] На линейке 15.x версия v15.5.29 закрывает три применимых адвизори, а кода Cache Components в 15.x нет вовсе, так что остальные четыре там не применяются.[1][3]
Честный способ узнать, что у вас стоит, - проверка на сервере, по задеплоенному артефакту, а не по памяти:
npm ls next
node -e "console.log(require('./.next/standalone/node_modules/next/package.json').version)"
npm ls next показывает, во что резолвится граф зависимостей; вторая команда - что реально попало в собранный standalone-бандл. Если они расходятся - ваш деплой отстаёт от намерения, и security-релиз тот самый момент, чтобы это исправить.
Проверенная процедура обновления standalone-сборки
Последовательность ниже предполагает стандартный self-hosted-стек, который мы разбираем в нашем гайде по деплою на VPS: standalone-сборка, node-рантайм, процесс под PM2 (или эквивалентным супервизором) и nginx спереди как reverse proxy. Security-обновление - тот же цикл, что обычный деплой, просто версия зафиксирована по адвизори.
Шаг 1 - Подтвердите affected-версию
Прочитайте нужное адвизори и отметьте и точный номер пропатченной версии, и то, попадает ли ваша текущая версия в affected-диапазон.[2] Если ваша линейка 16.x, цель - v16.4.5; если 15.x - v15.5.29.[1]
Шаг 2 - Обновите зафиксированную зависимость
На build-машине:
npm install next@16.4.5 # или next@15.5.29 на линейке 15.x
git add package.json package-lock.json
git commit -m "chore(deps): update next.js to 16.4.5 (November 2026 security release)"
Зафиксируйте версию и пусть lockfile несёт изменение, чтобы в review было видно, что именно уехало. Если вы проверяли, не важна ли для вашего image-пайплайна транзитивная зависимость (вроде sharp, которую пометил октябрьский батч), убедитесь, что она резолвится как надо:
npm ls sharp
Шаг 3 - Пересоберите standalone-артефакт
Запустите обычную продакшн-сборку с output: 'standalone', которая перегенерирует .next/standalone с пропатченным кодом - и любым пропатченным нативным модулем - внутри:[11]
npm run build
Сборка сама по себе на работающий сервер не влияет. Она только готовит артефакт, который вы сейчас задеплоите.
Шаг 4 - Задеплойте артефакт и перезапустите работающий процесс
Скопируйте новый .next/standalone (и статику) на сервер, затем перезапустите процесс фреймворка, чтобы работающий node-рантайм загрузил пропатченный код. Перезапуск обязателен: процесс держит старый код в памяти, пока вы его не перезапустите. Если у вас несколько инстансов - перезапустите все.
pm2 restart <app> # или: sudo systemctl restart next-app
Шаг 5 - Smoke-тест через nginx, а не в обход него
Поскольку ваш nginx-конфиг терминирует TLS и проксирует на приложение, тестируйте путь, которым реально ходят пользователи:
curl -I https://your-domain/ # ждём 200, отдано через nginx
curl -I https://your-domain/some-page
Дёрните динамический роут и API-роут, а если ваше приложение использует Cache Components - страницу или роут, который их задействует: там живёт большая часть этой пачки. Убедитесь, что pm2 status (или ваш супервизор) показывает процесс здоровым и в логах nginx нет всплеска 5xx.
Шаг 6 - Зафиксируйте версию «до/после»
Отметьте версию до и после апгрейда в ранбуке. Теперь есть две зафиксированные линейки - 16.4.5 и 15.5.29 - и знание о том, на какой из них вы, делает следующий адвизори почти холостым. Лёгкий ежемесячный npm outdated next по проектам ловит дрейф до следующего планового релиза.
Коротко
Next.js выпустил v16.4.5 (Active LTS) и v15.5.29 (Maintenance LTS) 3 ноября 2026 года, закрыв семь адвизори - одно высокое и шесть средних.[1] High-находка (GHSA-mfr8-8qww-v76h) раскрывает кешированные данные между тенантами при сочетании Cache Components и unstable_cache, а три адвизори прямо помечены self-hosted: отравление общего shell-кеша на next start, инжекция ответа между клиентами за HTTP/1.1 reverse-proxy и утечка HttpOnly-кук на Edge-роутах.[4][7][8][9] v15.5.29 закрывает три из семи; в 15.x нет кода Cache Components, в котором живут остальные четыре.[3] Поставьте next@16.4.5 (или next@15.5.29), пересоберите standalone-артефакт, перезапустите процесс и прогоните smoke-тест через nginx. На Vercel платформа патчит себя сама; на вашем VPS патч - это вы - и со стеком standalone + node + nginx из нашего гайда по деплою это двадцатиминутный проверяемый апгрейд.
Источники
- Next.js - «November 2026 Security Release» (2026-11-03): релиз v16.4.5 (Active LTS) и v15.5.29 (Maintenance LTS); семь адвизори, одно высокой и шесть средней severity; команды
npm install next@16.4.5/npm install next@15.5.29; оценка GHSA-mfr8-8qww-v76h как high. https://nextjs.org/blog/november-2026-security-release - checked 2026-11-04 - GitHub - релиз vercel/next.js v16.4.5 (2026-11-03): закрывает все семь адвизори этой пачки. https://github.com/vercel/next.js/releases/tag/v16.4.5 - checked 2026-11-04
- GitHub - релиз vercel/next.js v15.5.29 (2026-11-03): закрывает GHSA-pc58-hwjq-p385, GHSA-7qx7-33qx-rqx2 и GHSA-f3mh-rxg3-f5g2 (3 из 7). https://github.com/vercel/next.js/releases/tag/v15.5.29 - checked 2026-11-04
- GitHub Security Advisory GHSA-mfr8-8qww-v76h - раскрытие информации между root-параметрами, когда функция
use cacheвызывается черезunstable_cache(); affected >= 16.3.0. https://github.com/vercel/next.js/security/advisories/GHSA-mfr8-8qww-v76h - checked 2026-11-04 - GitHub Security Advisory GHSA-vc7v-qv4w-wrv8 - утечка кеша между значениями root-параметров во вложенных
use cacheчерез отложенные метаданные внутреннего потока; affected 16.2.0 - 16.4.2. https://github.com/vercel/next.js/security/advisories/GHSA-vc7v-qv4w-wrv8 - checked 2026-11-04 - GitHub Security Advisory GHSA-rhh4-g77r-r9qj - раскрытие и отравление кеша между пользователями в
use cacheс бинарными аргументами; affected 16.0.0 - 16.4.2. https://github.com/vercel/next.js/security/advisories/GHSA-rhh4-g77r-r9qj - checked 2026-11-04 - GitHub Security Advisory GHSA-vvgp-ww4w-46vf - отравление общего fallback-shell в Cache Components через подставленные из запроса placeholder route-параметры (
next start, Partial Prefetching unset/false; workaroundpartialPrefetching: true); affected >= 16.4.0. https://github.com/vercel/next.js/security/advisories/GHSA-vvgp-ww4w-46vf - checked 2026-11-04 - GitHub Security Advisory GHSA-pc58-hwjq-p385 - инжекция и раскрытие ответа между клиентами через устаревший сжатый framing за HTTP/1.1 reverse-proxy. https://github.com/vercel/next.js/security/advisories/GHSA-pc58-hwjq-p385 - checked 2026-11-04
- GitHub Security Advisory GHSA-f3mh-rxg3-f5g2 - утечка HttpOnly-cookie через внутренний заголовок
x-middleware-set-cookieна Edge-рантайм-роутах; Node-рантайм-роуты иcookies().set()не затронуты. https://github.com/vercel/next.js/security/advisories/GHSA-f3mh-rxg3-f5g2 - checked 2026-11-04 - GitHub Security Advisory GHSA-7qx7-33qx-rqx2 - обход запрета SVG в Image Optimization (ошибочная классификация как AVIF); allowlist источников изображений продолжает действовать. https://github.com/vercel/next.js/security/advisories/GHSA-7qx7-33qx-rqx2 - checked 2026-11-04
- Next.js - справочник конфигурации
output(сoutput: 'standalone'командаnext buildсоздаёт.next/standalone- самодостаточную папку, деплоящуюся без установкиnode_modules; строится через output file tracing). https://nextjs.org/docs/app/api-reference/config/next-config-js/output - checked 2026-11-04