Повернутися до блогу
Web Security4.07.2026

SSRF і метадані хмари: як один серверний запит краде ваші облікові дані

Server-Side Request Forgery (SSRF) невипадково отримала окреме місце A10:2021 в OWASP Top 10: це одна з небагатьох вразливостей, що дозволяє зовнішньому атакувальнику виконувати запити зсередини вашої інфраструктури, користуючись довірою, яку вже мають ваші сервери. Єдиний неперевірений параметр URL може стати мостом із публічного інтернету прямо до внутрішніх сервісів, приватних API і — що найнебезпечніше — до ендпоінту метаданих хмари, який видає тимчасові облікові дані.

Що таке SSRF насправді

SSRF виникає щоразу, коли застосунок завантажує віддалений ресурс за URL (чи за хостом або IP), на який може впливати користувач, без перевірки того, куди такому запиту взагалі дозволено йти. Класичні точки — проксі зображень, валідатори вебхуків, генератори прев'ю посилань, рендерери PDF, імпортери документів і будь-яка функція «імпорт за URL». Сервер застосунку слухняно виконує запит від імені атакувальника, а оскільки він за файрволом, дотягується туди, куди сам атакувальник напряму ніколи б не потрапив.

Канонічна відповідність — CWE-918: Server-Side Request Forgery. Неавтентифікований, віддалено експлуатований SSRF, що читає хмарні облікові дані, зазвичай отримує оцінку в діапазоні CVSS 9.1–9.9 — наприклад AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:L/A:N, де прапорець Scope: Changed відображає стрибок із веб-рівня в площину хмарної ідентичності.

Ланцюг атаки крок за кроком

Розгляньмо ендпоінт, що генерує прев'ю посилань:

  • 1. Виявлення. Атакувальник знаходить POST /api/preview {"url":"https://example.com/article"} і помічає, що відповідь вбудовує завантажений вміст. Він підставляє http://127.0.0.1:8080/ й отримує внутрішню адмін-сторінку — SSRF підтверджено.
  • 2. Внутрішня розвідка. Він промацує http://169.254.169.254/, діапазони 10.0.0.0/8 та типові порти (Redis 6379, Elasticsearch 9200, Consul 8500), щоб зрозуміти, до чого сервер здатен дотягнутися.
  • 3. Удар по сервісу метаданих. В AWS зі старим IMDSv1 звичайний GET на http://169.254.169.254/latest/meta-data/iam/security-credentials/ повертає ім'я прив'язаної ролі IAM, а його дописування — JSON із AccessKeyId, SecretAccessKey і Token.
  • 4. Крадіжка облікових даних і бічне переміщення. Атакувальник експортує тимчасові ключі, виконує aws sts get-caller-identity й діє вже як роль інстансу EC2 — читає бакети S3, таблиці DynamoDB, а за надмірних прав ескалює по всьому акаунту.

Злам Capital One 2019 року — понад 100 мільйонів записів — відбувся саме за цією схемою: SSRF проти неправильно налаштованого компонента досяг ендпоінту метаданих, забрав облікові дані ролі й дозволив вивантажити дані з S3.

Чому 169.254.169.254 такий небезпечний

Блок 169.254.0.0/16 — це діапазон IPv4 link-local (RFC 3927). Кожна велика хмара прив'язує свій Instance Metadata Service (IMDS) до 169.254.169.254 — AWS, Google Cloud (через metadata.google.internal) та Azure. За задумом він неавтентифікований: будь-який процес на хості, включно з вашим застосунком, що робить вихідний запит, може його прочитати. Це не проблема, доки ціль запиту обирає не атакувальник.

Обходи, які пропускають захисники

Наївні блок-листи, що звіряють лише рядок «169.254.169.254» чи «localhost», не встоять проти:

  • Альтернативних кодувань IP: http://2852039166/ (десяткове), http://0xA9FEA9FE/ (шістнадцяткове) або http://[::ffff:169.254.169.254]/ (IPv6-mapped).
  • DNS rebinding: ім'я хоста, що під час валідації розв'язується в безпечний IP, а під час самого завантаження — у 169.254.169.254 (TOCTOU між перевіркою та використанням).
  • Редиректів: вказаний URL повертає 302 на внутрішню адресу, за якою йде HTTP-клієнт.
  • Альтернативних схем: file://, gopher:// або dict://, щоб дістати внутрішні сервіси поза HTTP.

Захист, що справді працює

Застосовуйте ці шари разом — жоден окремий контроль недостатній:

  • Увімкніть IMDSv2 і hop-limit 1. IMDSv2 вимагає токен сесії, отриманий запитом PUT із заголовком X-aws-ec2-metadata-token-ttl-seconds; SSRF через звичайний GET (найпоширеніший випадок) такий токен створити не може. Встановіть інстансу HttpTokens=required і HttpPutResponseHopLimit=1, щоб контейнери не дотягувалися до метаданих. Це єдине виправлення з найвищою цінністю.
  • Allow-лист, а не блок-лист. Перевіряйте ціль за явним allow-листом схем (лише https), хостів і портів. Усе інше відхиляйте за замовчуванням.
  • Розв'яжіть, потім зафіксуйте. Розв'яжіть ім'я хоста в IP, переконайтеся, що він публічний (відхиліть приватні RFC 1918, loopback, link-local 169.254.0.0/16 та еквіваленти IPv6), потім під'єднуйтеся до саме цього IP — закриваючи вікно DNS rebinding. Повторюйте валідацію після кожного редиректу та вимикайте автоматичне слідування, де можливо.
  • Контроль вихідного трафіку. Розмістіть завантажувальне навантаження в підмережі з групою безпеки / файрволом, що забороняє вихідний трафік до IP метаданих і внутрішніх діапазонів. Глибокий захист на випадок обходу валідації на рівні застосунку.
  • Мінімальні привілеї IAM. Виходьте з того, що облікові дані витечуть; обмежте роль інстансу мінімумом і використовуйте короткі TTL, щоб украдені токени швидко спливали.

SSRF дешевий в експлуатації та катастрофічний, коли влучає в сервіс метаданих. Вважайте будь-який контрольований користувачем URL ворожим, валідуйте на рівні розв'язаного IP і ввімкніть IMDSv2 вже сьогодні — це безкоштовна зміна конфігурації, що нейтралізує найпоширеніший шлях атаки.

SSRFOWASPcloud-securityIMDSv2AWScredential-theft