Сервисов становится всё больше, а шлюзы, через которые они общаются с внешним миром, превратились в жизненно важный элемент архитектуры. К сожалению, именно здесь часто прячутся мелкие, на первый взгляд, огрехи, превращающие защитный барьер в распахнутые двери. В этом материале разберём, как обычная невнимательность при настройке API Gateway открывает возможность обойти авторизацию, и что с этим делать.
Почему обход авторизации через API Gateway остаётся проблемой
Кажется, что современная облачная инфраструктура «из коробки» достаточно безопасна. Но статистика инцидентов доказывает обратное: ежегодно публично фиксируются десятки утечек, где корнем проблем были всего пара неправильно выставленных галочек в консоли. Атакующему даже не нужно искать сложные 0-day — достаточно дождаться новой версии приложения, когда инженер спешил на релиз и временно снял галочку «Авторизация — обязательна», а вернуть забыл.
Что такое API Gateway и какие механизмы авторизации он предоставляет
API Gateway — это прокси-слой между клиентами и набором микросервисов. Он маршрутизирует запросы, трансформирует их и, главное, проверяет, можно ли пользователю выполнить тот или иной метод. В зависимости от платформы доступны разные способы авторизации:
- OAuth 2.0 / OpenID Connect — токен-аутентификация, совместимая с большинством современных клиентов.
- IAM-политики (AWS, GCP, «Яндекс Облако») — правила на уровне аккаунта, задающие, кто и что может вызывать.
- Ключи доступа (API keys) — простые токены, которые передаются в заголовке или строке запроса.
- Lambda-авторизаторы / custom authorizers — кастомная функция, которая валидирует запрос по собственным правилам.
На практике разработчики комбинируют методы: например, публичные эндпоинты защищают по API key, а внутренние — по JWT. Чем сложнее схема, тем выше шанс упустить несогласованность настроек.
Типовые ошибки конфигурации, которые приводят к обходу авторизации
Ниже — семь сценариев, нередко встречающихся на аудите и bug bounty. Названия полей могут отличаться в разных облаках, но суть одинакова.
- Метод «ANY» без авторизации. В UI удобно выбрать «ANY», чтобы одно правило принимало сразу GET, POST, DELETE и другие методы. Если при этом для конкретного метода авторизация включена, а для «ANY» — нет, атакующий вызывает
PATCH /resource
и проходит мимо проверок. - Разные стадии (stages), разные правила. Допустим, есть dev, staging и prod. Часто забывают, что политика копируется не автоматически: в релиз уходит незащищённая стадия, и обнаруживается это лишь после инцидента.
- Кэш авторизации. Чтобы снизить задержку, шлюз кеширует результат проверки токена, например, на пять минут. Если в кэше останется решение «разрешить», а роль пользователя уже отозвана, старый токен может продолжать работать.
- Избыточные wildcard-правила. Политика вида
"arn:aws:execute-api:*:*:*/GET/*"
проще, чем перечислять каждый путь, однако она разрешает доступ ко всем ресурсам — даже тем, что должны быть приватны. - Неучтённые роли интеграции. Авторизацию прошли, но дальше запрос идёт к бэкенду от имени роли, у которой прав больше, чем нужно. В итоге «ограниченный» пользователь превращается в админа на уровне базы.
- Функция авторизации возвращает не тот статус. Кастомный authorizer должен отвечать
403
, если что-то не так. Некоторые разработчики по ошибке возвращают200
с текстом ошибки; для шлюза это сигнал «всё в порядке» — запрос проходит. - Параллельный endpoint без авторизации. При миграции версий API старый путь (например
/v1/…
) оставляют «для совместимости» и привязывают к нему упрощённый маршрут. Если для нового/v2/…
авторизация обязательна, а унаследованный/v1/…
не закрыли, злоумышленник обращается к старому пути и получает тот же функционал без токена.
Сценарий из практики: как атакующий пользуется конфигурационной дырой
Представим SaaS-сервис, который хранит пользовательские отчёты. В /reports/{id} добавили метод DELETE, но забыли включить авторизацию на «ANY» — тестировщик отлаживал сервис через Postman.
- Атакующий методом
OPTIONS /reports/123
проверяет, какие методы доступны. - Замечает, что
DELETE
не требует авторизации. - Отправляет
DELETE
, и шлюз исполняет запрос, потому что правило «ANY» работает без токена. - Отчёт пользователя удалён, журнал активности пуст — авторизация ведь «не сбойнула».
В облаке это может дополниться цепочкой из бессрочных temporary credentials, уязвимого S3-бакета или просочившегося в логи JWT. Итог одинаков: конфигурационная оплошность превращается в эксплойт без сложного кода.
Как обнаружить проблему на раннем этапе
Большинство багов типа «галочка не там» отлично ловятся автоматикой, если она настроена.
- Инструменты вроде OWASP ZAP и Scout Suite . Прогоняют облачный аккаунт и подсвечивают правила с wildcard-ами.
- CI/CD-проверки инфраструктурного кода. Если конфигурации (Terraform, CloudFormation, Pulumi) хранятся в Git, запускайте Checkov или KICS на каждый pull request.
- Security Hub / CloudTrail-алерты. Любая аномалия (например, массовые DELETE-запросы без токена) должна поднимать инцидент в Slack или SIEM.
- Ротация тестовых стадий. Если в dev для удобства отключали авторизацию, автоматический скрипт должен возвращать настройки по умолчанию перед слиянием в prod.
Пошаговая стратегия аудита для DevOps и безопасников
- Соберите инвентаризацию. Выгрузите список всех API Gateway, стадий, доменных имён, привязанных к аккаунту.
- Сгруппируйте их по контексту доступа. Публичные, приватные, партнёрские.
- Проверьте каждый ресурс-метод. Есть ли у него authorizer, и какой — ключ, IAM или JWT.
- Сравните декларативную и фактическую конфигурации. Terraform говорит, что защита включена, но в консоли она выключена? Срочно ищите причину.
- Проведите negative-тестирование. Отправьте запрос без токена и ожидайте
401
. Получили200
? Значит, где-то дыра. - Проверьте роли интеграций. Убедитесь, что запрос от имени шлюза не имеет сверхправ.
- Заведите регрессионные тесты. Каждый новый endpoint сначала должен упасть без авторизации — это обязательный тест-кейс.
Лучшие практики защиты
- Принцип явного запрета. Разрешайте доступ только тому, что описано в политике, не используйте wildcard.
- Infrastructure as Code. Храните конфигурации шлюза как код, чтобы «горячих» правок через UI не было.
- Включите логирование на уровне шлюза. Это дёшево и очень помогает расследованию.
- Гранулируйте роли. Пусть API Gateway вызывает бэкенд от имени отдельной сервис-роли с минимальными правами.
- Регулярные проверки третьей стороной. Договаривайтесь с аудиторами искать именно конфигурационные ошибки, а не только инъекции.
- Держите движок шлюза обновлённым. Многие уязвимости закрываются патчами.
Инструменты, которые помогают каждый день
Ниже полезные сервисы, снимающие часть рутины:
- OWASP ZAP — экспресс-проверка на базовые уязвимости.
- Burp Suite — универсальный инструмент для ручного тестирования API.
- Scout Suite — аудит облачных настроек.
- IAM Access Analyzer — подсветит избыточно открытые ресурсы в AWS.
- Semgrep — статический анализ кода и IaC-файлов.
- Grafana Loki + Prometheus — бюджетный стек для логов и алертинга.
Часто задаваемые вопросы
Можно ли отключить авторизацию на время отладки?
Можно, но только локально или в изолированном тестовом аккаунте, который не виден интернету. Любая «временная» поблажка на боевом окружении почти наверняка забудется.
Достаточно ли поставить WAF перед шлюзом?
Веб-фаервол ловит SQL-инъекции и XSS, но никак не защитит от «авторизация отключена». Поэтому WAF — полезное, но вспомогательное средство.
Что делать, если баг уже ушёл в прод?
Сначала закройте дыру: включите авторизацию, ограничьте подозрительные IP, отзовите выданные ключи. Затем изучите логи, чтобы понять масштаб проникновения. И, наконец, внедрите процесс, исключающий повторение: code-review, автоматические сканеры и контроль через pull request.
Заключение
Чтобы у атакующего не было шанса пройти мимо авторизации, придерживайтесь принципа минимально достаточных прав, храните конфигурации инфраструктуры в системе контроля версий, автоматизируйте проверки и рассматривайте безопасность как неотъемлемую часть жизненного цикла разработки.
Проводите тесты на проникновение только в тех системах, для которых у вас есть официальное разрешение. Несанкционированный доступ противозаконен.