Достаточно ли защищен ваш GraphQL API?
На связи Юлия Полозкова, ведущий разработчик отдела архитектурных решений и перспективной разработки «БАРС Груп». Наша команда специализируется на создании бизнес-приложений для государственного и корпоративного сектора. В этой статье делюсь опытом, как обеспечить достаточный уровень кибербезопасности.
В частности, разбираю техники и средства защиты Graph API, такие как отключение интроспекции средствами HotChocolate, лимиты размеров запроса, его глубины вложенности и количества запрашиваемых объектов. Ведь если ваше приложение – публично доступный сервис, то одной аутентификацией не обойтись. Вам стоит задуматься о безопасности, защите данных и самого веб-сервиса от злоумышленников.
Давайте рассмотрим, что такое интроспекция, почему опасно оставлять ее включенной и как ее отключать. Также разберем дополнительные средства защиты.
Интроспекция или самоанализ
Интроспекция позволяет запрашивать у сервера GraphQL информацию о базовой схеме, например: типы данных, поля, запросы, мутации и описание самих полей. Запрос схемы – это такой же обычный графовский запрос, как и другие.
Пример базовой схемы одного из наших проектов:
Интроспекция полезна на стадии разработки, т.к. используется некоторыми инструментами, с которыми работают разработчики, например: GraphQL IDEs, GraphQL, Postman. GraphQL IDEs обычно применяет ее, чтобы помогать тестированию и диагностике схемы во время разработки, а GraphQL – для подсказок при наборе запросов и их валидации.
Интроспекция в производственном окружении
Как уже было упомянуто ранее, используя интроспекцию можно раскрыть конфиденциальные данные о вашем приложении. Например, описание поля, где может быть указана какая-то часть бизнес-логики, которая должна быть скрыта от посторонних глаз. Да и в целом, нежелательно раскрывать подробности того, что умеет ваш сервис всем подряд. Более того, сами запросы интроспекции могут быть громоздкими и расходовать много ресурсов сервера. И при этом, по умолчанию, они доступны без аутентификации. Именно поэтому стоит отключать интроспекцию в продакшене.
О том, какие атаки бывают на сервисы GraphQL можно почитать тут.
Как отключить интроспекцию
HotChocolate дает возможность гибко настраивать условия отображения схемы. Для начала рассмотрим, как отключить интроспекцию в вашем проекте. Для этого необходимо при подключении GraphQL вызывать метод AddIntrospectionAllowedRule(), что спрячет схему от всех запросов. Вот фрагмент кода из файла Program.cs
Если нужно отключать схему по определенным условиям, надо создать свой обработчик запросов к GraphQL конфигурации и в нем определить условия, при которых будут доступны запросы интроспекции, например, проверять аутентифицирован ли пользователь:
Также добавить кастомный обработчик после регистрации GraphQL сервера.
Дополнительная защита GraphQL API
Широкие возможности GraphQL позволяют удобно работать с данными, получать только те из них, которые вам нужны. Но эта гибкость также несет в себе некоторые последствия для безопасности. Например, злоумышленник может создать дорогой запрос, который перегрузит сервер, базу данных, сеть или все это вместе взятое. Без правильной защиты система может подвергнуться DoS-атакам.
Рассмотрим пример, когда у приложения есть сущности, которые имеют ссылки друг на друга. Так, на картинке ниже сущность Package ссылается на PackageCategory, а PackageCategory – на Package.
В таком случае, можно написать бесконечной вложенности запрос, как показано на скриншоте ниже. Тут вложенность не слишком большая – 21 запрос, но выполнение запроса уже заняло 5 секунд:
Понятно, что подобный запрос увеличивает объемы запрашиваемых объектов экспонентно и может повлиять на работу сервера. Поэтому следует вводить ограничения на вложенность и размеры запросов.
Ограничение размеров запроса
Тут все просто – создается Middleware, который проверяет длину запроса. Можно ограничиться двумя тысячами байтов и, если запрос больше, то не пропускать его в дальнейшую обработку конвейером запросов.
Однако этого недостаточно, ведь, если у приложения короткие названия полей, то все еще можно написать запрос с высокой вложенностью.
Ограничение вложенности запросов
HotChocolate дает возможность определять правила валидации запросов, в том числе и правило для вложенности запроса. Добавить их можно так же, как и правило интроспекции при подключении в проект GraphQL. Ниже добавляется валидация на вложенность не более пяти:
При написании сложного запроса увидим такую ошибку:
Также можно создавать свои кастомные правила валидации сложности запросов, об этом более детально можно прочитать тут.
Ограничение количества запрашиваемых объектов
Еще один вредный для сервера аспект – это запрос большого количества объектов за раз. Такой запрос всегда будет дорогим и для базы данных, и для сети. Чтоб избежать подобных ситуаций, рекомендуется использовать атрибут «UseOffsetPaging» предоставляемый HotChocolate с параметром «MaxPageSize» у тех запросов, которые поддерживают пагинацию:
Благодаря этому атрибуту мы получим ошибку, если запросим больше 10 объектов:
Подытожим
GraphQL перспективная современная технология, которая позволяет быстрее разрабатывать веб-приложения, но всегда нужно помнить о безопасности. Перечисленные в статье механизмы обеспечения безопасности – это базовые механизмы, которые в совокупности дают достаточный уровень защиты вашего API.