FlawOpen

flawopen.com/SSRF/SSRF в Node.js fetch()

Защищает ли Node.js fetch() от SSRF?

CWE-918: Server-Side Request ForgeryСправочник по безопасности Node.js
Простыми словами

Нет. Серверный fetch() отправляет запрос от имени сервера. Если вызывающий выбирает адрес, он может направить сервер к системам, недоступным напрямую. Это как попросить курьера доставить посылку без проверки адреса. Риск зависит от сети, учётных данных, правил URL и перенаправлений.

SSRF (CWE-918)Сервер запрашивает адрес, выбранный или изменённый недоверенным вызывающим, пересекая границу сетевого доверия.
Список разрешённых целейФиксированное сопоставление пользовательского выбора вроде providerId с источником, настроенным приложением. Не принимает произвольные URL.
Проверка перенаправленийОтвет может указать другой адрес. Автоматический переход обходит проверку только исходного URL.
DNS rebindingИмя может разрешаться в разные IP. Проверка DNS один раз с последующим новым разрешением в HTTP-клиенте создаёт окно TOCTOU.

Причина: сервер доверяет выбранному пользователем адресу

Node.js fetch() — универсальный HTTP-клиент, а не политика защиты от SSRF. Он не ограничивает доступные сети; браузерный CORS не создаёт такую границу на сервере. Разобрать URL недостаточно: разрешённое имя может указывать на запрещённый адрес, а ответ перенаправить на другой хост. Функции загрузки аватаров, webhook, документов или предпросмотра по URL пользователя могут открыть этот путь.

Как запрос пересекает границу доверия

Step 1

Пользователь влияет на URL

Эндпоинт принимает полный URL или данные для его построения, например для предпросмотра изображения.

Step 2

Сервер отправляет запрос

HTTP-клиент использует сетевой маршрут, DNS, прокси и права процесса сервера.

Step 3

Перенаправление меняет адрес

Fetch по умолчанию следует перенаправлениям. Сначала разрешённый адрес может вернуть Location на запрещённый хост.

Step 4

Ответ открывает доступные данные

Если сеть и правила это допускают, становятся доступны внутренние сервисы или облачные метаданные. Это зависит от окружения.

Уязвимый и более безопасный код Node.js

Уязвимо
// Не загружайте произвольный URL от вызывающего.
const response = await fetch(userProvidedUrl);
Безопаснее
// Пользователь выбирает ключ, а не сетевой адрес.
const destinations = new Map([
  ["status", new URL("https://status.example/")],
  ["docs", new URL("https://docs.example/")],
]);

const target = destinations.get(providerId);
if (!target) throw new Error("Unknown provider");

const response = await fetch(target, {
  redirect: "error",
  signal: AbortSignal.timeout(3000),
});
if (!response.ok) throw new Error("Upstream request failed");

Если пользователи должны указывать URL

Предпочитайте идентификатор провайдера с фиксированным адресом. Если нужны произвольные публичные URL, разрешайте только необходимые схемы и порты; отклоняйте user-info, loopback, частные, link-local и другие запрещённые IPv4/IPv6-адреса. Проверяйте все DNS-адреса и подключайтесь именно к проверенному адресу без повторного непроверенного разрешения. Отключайте перенаправления или проверяйте каждый переход. Ограничивайте исходящий трафик, включая адреса метаданных 169.254.169.254 и включённый IPv6 endpoint. Ограничьте время, размер ответа и параллелизм; не передавайте внутренние учётные данные.

Список защиты от SSRF

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

Достаточно ли блокировать localhost и частные IP?

Нет. Перенаправления, варианты IPv4/IPv6, DNS rebinding, прокси и гонки между разрешением и подключением обходят простую проверку. Используйте список разрешённых целей. Для произвольных адресов проверяйте каждый IP и подключайтесь именно к нему; применяйте те же правила на сетевом выходе.

Устраняет ли IMDSv2 SSRF?

Нет. IMDSv2 требует токен и снижает часть рисков, но SSRF может достигать других внутренних служб или метаданных при иной конфигурации. Контроль адресов и исходящего трафика всё равно нужен.

Первичные источники

Другие темы безопасности и разборы инцидентов:Полный каталог безопасности →
См. также Подделка запросов на стороне сервера (SSRF, CWE-918): как работает и как предотвратить на любом языке — flawopen.com SSRF и облачные метаданные: риски и защита ИИ-боты PR: защита от SSRF — flawopen.com