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