// Безопасность / Веб

SSRF: подделка запросов на стороне сервера

SSRF — подделка запросов на стороне сервера

SSRF (Server-Side Request Forgery, подделка запросов на стороне сервера) — уязвимость, при которой атакующий заставляет ваш сервер отправить запрос по произвольному адресу. Запрос идёт изнутри периметра и потому достаёт то, что снаружи недоступно: внутренние сервисы, облачные метаданные, локальные порты. SSRF вошёл в OWASP Top 10 2021 отдельной категорией (A10) — редкий случай, когда один класс уязвимости получает собственное место в рейтинге. Частая находка на пентесте.

Как работает атака

Любая функция, которая ходит по URL, полученному от пользователя, — потенциальный SSRF. Загрузка картинки по ссылке, вебхук, генератор PDF/превью, импорт, проверка ссылки:

POST /api/avatar/from-url
{ "url": "https://i.imgur.com/cat.png" }   // задумано так

--- атака ---
{ "url": "http://169.254.169.254/latest/meta-data/iam/security-credentials/" }
// сервер сам сходит к облачным метаданным и вернёт ключи AWS

Реальный масштаб: взлом Capital One

В 2019 году SSRF стал причиной одной из крупнейших утечек в истории финсектора: через SSRF в приложении на AWS атакующий добрался до сервиса метаданных (169.254.169.254), получил временные IAM-ключи и выкачал данные ~100 млн клиентов из S3. Итог — штраф $80 млн. Это каноничный пример, почему «безобидная» загрузка по URL стоит миллионов.

Виды SSRF

  • Basic (с ответом): ответ внутреннего запроса возвращается атакующему.
  • Blind (слепой): ответ не виден, но факт запроса подтверждается через свой сервер/DNS (полезно для сканирования и эксплуатации по времени).
  • Через нестандартные схемы: gopher://, dict://, file:// — позволяют слать произвольные пакеты внутренним сервисам (Redis, SMTP) и читать файлы.
  • DNS rebinding: обход allow-list подменой DNS-ответа после проверки.

Что достаёт атакующий

  • Облачные метаданные и временные ключи (AWS/GCP/Azure) — 169.254.169.254.
  • Внутренние сервисы без аутентификации (админки, Redis, Elasticsearch, k8s API).
  • Сканирование внутренней сети и портов (по времени ответа).
  • Чтение локальных файлов через file://.
  • Цепочку до RCE (например, через незащищённый внутренний сервис).

Защита: рабочие меры

  1. Allow-list адресов назначения. Разрешайте только заранее известные хосты/домены — это единственная по-настоящему надёжная мера.
  2. Запрет приватных диапазонов. Блокируйте 127.0.0.0/8, 10/8, 172.16/12, 192.168/16, 169.254/16 — и проверяйте адрес ПОСЛЕ резолва DNS (против rebinding).
  3. Только нужные схемы. Разрешить http/https, запретить gopher/dict/file.
  4. IMDSv2 в облаке. Требует токен-сессию, что резко усложняет кражу метаданных через SSRF (главный урок Capital One).
  5. Отдельная сеть/прокси для исходящих запросов приложения, без доступа к внутренним сервисам.
  6. Не возвращайте сырой ответ внутреннего запроса пользователю.

Пример базовой серверной проверки (концептуально):

const ip = await dns.resolve(new URL(userUrl).hostname);
if (isPrivate(ip) || isLinkLocal(ip)) throw new Error("blocked");  // 169.254/10/172.16/192.168
if (!["http:","https:"].includes(new URL(userUrl).protocol)) throw new Error("scheme");
// + перепроверка ip непосредственно перед запросом (против TOCTOU/rebinding)

Экспертное наблюдение: SSRF почти всегда живёт в «интеграционных» функциях, которые писали в спешке — импорт по ссылке, вебхуки, генераторы отчётов, интеграции с внешними API. Это первое, что мы проверяем, найдя любую форму «вставьте URL».

Как это тестируется

SSRF ищется вручную: перечисляем все места, где приложение обращается по URL, и подставляем внутренние адреса и нестандартные схемы, отслеживая ответы и обращения на наш контрольный сервер (для blind). Проверяем в рамках пентеста веб-приложений и пентеста API.

Может ли ваш сервер сходить во внутреннюю сеть по команде извне?

Проверим все точки, где приложение ходит по URL, и найдём SSRF — включая слепой и облачные метаданные.

Заказать пентест →

Читайте также: Безопасность API, Аудит облачной инфраструктуры.

← назад в блог