Безопасность GraphQL: глубина, сложность, персистентные запросы
↑ 5.3 GraphQL на бэкенде и Federation · ← Предыдущая
Зачем это на собесе
Гибкость GraphQL — и уязвимость: без ограничений один запрос может положить сервер.
Объяснение
Клиент строит запросы сам, поэтому сервер обязан ограничивать ресурсы.
| Угроза | Защита |
|---|---|
Глубокие вложенные запросы (a{b{a{b...}}}) | ограничение глубины (AddMaxExecutionDepthRule) |
| Дорогие запросы | анализ стоимости/сложности, лимиты |
| Огромные списки | MaxPageSize, обязательный first |
| Batching/alias-атаки (100 логинов в одном запросе) | лимит алиасов/операций, rate limiting по стоимости |
| Introspection в проде | отключить или ограничить |
| Неавторизованный доступ к полям | [Authorize] на полях, политики |
| Инъекции | параметры/переменные, валидация входа |
| Утечка ошибок | скрывать детали исключений |
builder.Services.AddGraphQLServer()
.AddMaxExecutionDepthRule(8)
.ModifyCostOptions(o => { o.MaxFieldCost = 1000; o.EnforceCostLimits = true; })
.AddAuthorization()
.DisableIntrospection(!builder.Environment.IsDevelopment());Persisted queries
Клиенты заранее регистрируют запросы (по хэшу), а в проде принимаются только известные запросы. Это снижает трафик и полностью исключает произвольные тяжёлые запросы (allowlist).
Нюансы и подводные камни
- Введите тайм-аут выполнения запроса.
- Ограничивайте не только количество запросов, но и их стоимость.
- Subscription-соединения требуют лимитов и аутентификации.
- Схема раскрывает структуру данных: отключайте introspection и подсказки полей в проде для публичных API.
Практика
- Включите лимит глубины и проверьте рекурсивный запрос.
- Настройте persisted queries и allowlist.
- Добавьте авторизацию на конфиденциальное поле.
Вопросы с ответами
Как защитить GraphQL от тяжёлых запросов?
Лимиты глубины и стоимости, ограничение размера страниц, таймауты, persisted queries.
Зачем persisted queries?
Сервер выполняет только заранее известные запросы: меньше трафика и нет произвольных запросов от клиента.