В первой части серии «Взлом GraphQL» мы собираемся обсудить основы GraphQL и то, как злоумышленники могут использовать этот сервис.
GraphQL решает множество проблем, с которыми сталкиваются разработчики при работе с REST API, например получение большего количества данных, чем необходимо, или необходимость иметь новую конечную точку для каждого вызова.
Выдержка из официальной документации:
Пример запроса GraphQL:
Запрос: запрос используется для чтения данных.
Запрос и ответ имеют схожий формат, демонстрируя, что вы получите то, о чем просите в GraphQL. Например, в приведенном выше блоке кода мы запросили заголовок. Это означает, что мы получим заголовок в последующем ответе.
Мутация: Мутация используется для вставки, обновления или удаления данных.
Например, на скриншоте выше показана мутация, добавляющая новую заметку Todo. В случае успеха он вернет идентификатор и дату создания недавно вставленной заметки Todo.
Некоторые распространенные конечные точки GraphQL:
Трудно перечислить все конечные точки в экземпляре GraphQL, но во многих реализациях используется такая структура, как Appollo. В следующем разделе перечислены общие конечные точки, используемые в реализациях GraphQL:
Схема GraphQL лежит в основе любой реализации сервера GraphQL. В нем описываются функции, доступные клиентам, которые подключаются к экземпляру GraphQL. Это похоже на план, который клиенты могут узнать, запросив его.
Самоанализ:
Чтобы получить схему, мы можем отправить HTTP-запрос на конечную точку сервера GraphQL с запросом схемы GraphQL. Этот тип HTTP-запроса называется запросом самоанализа GraphQL.
Самоанализ — это основная возможность запрашивать, какие ресурсы доступны в схеме. При самоанализе мы можем увидеть запросы, типы, поля и директивы, которые он поддерживает. К сожалению, запрос самоанализа включен по умолчанию, поэтому его стоит попробовать во время теста на проникновение.
Как отправить запрос на самоанализ?
Запрос самоанализа дает нам подробную информацию о запросах, типах, полях и директивах, которые поддерживаются GraphQL, и по умолчанию мы можем использовать запрос самоанализа для каждого экземпляра GraphQL. Давайте посмотрим на запрос самоанализа в действии.
Шаг 1: Перехватите HTTP-запрос с помощью Burp Suite:
Шаг 2: Отправьте HTTP-запрос на Burp Repeater:
Посмотреть вложение 38323
Шаг 3: Замените тело POST общим запросом самоанализа, чтобы получить всю внутреннюю схему. Для этого мы использовали расширение GraphQL Raider для Burp Suite.
Шаг 4. Запишите схему для сбора конфиденциальных вызовов API.
Пример запроса на самоанализ:
Ответ может быть довольно большим и трудным для понимания. Лучший способ понять ответ — визуализировать его. Это можно сделать с помощью инструмента «Вояджер».
Чтобы получить тот же результат, что и выше, выполните запрос на самоанализ цели и вставьте ответ в инструмент «Вояджер». Используя этот метод, злоумышленники могут легко идентифицировать конфиденциальные вызовы API и использовать их.
ОРИГИНАЛЬНАЯ СТАТЬЯ
Что такое GraphQL?
Проще говоря, GraphQL — это язык запросов для конечных точек API. Он взаимодействует с конечными точками API и извлекает данные из серверной части. Это альтернатива стандартам API, таким как REST и SOAP. Он может делать большинство вещей, которые могут делать стандартные конечные точки REST API, а иногда даже больше, более эффективным и контролируемым образом.GraphQL решает множество проблем, с которыми сталкиваются разработчики при работе с REST API, например получение большего количества данных, чем необходимо, или необходимость иметь новую конечную точку для каждого вызова.
Выдержка из официальной документации:
GraphQL — это язык запросов для вашего API и среда выполнения на стороне сервера для выполнения запросов с использованием системы типов, которую вы определяете для своих данных. GraphQL не привязан к какой-либо конкретной базе данных или механизму хранения, а вместо этого поддерживается вашим существующим кодом и данными.
Пример запроса GraphQL:
Тип запросов:
В GraphQL есть 2 основных типа запросов — запрос и мутация.Запрос: запрос используется для чтения данных.
Код:
{
"data":{
"todos":[
{
"title": "Learn GraphQL"
},
{
"title": "Learn about queries"
}
]
}
}
Запрос и ответ имеют схожий формат, демонстрируя, что вы получите то, о чем просите в GraphQL. Например, в приведенном выше блоке кода мы запросили заголовок. Это означает, что мы получим заголовок в последующем ответе.
Мутация: Мутация используется для вставки, обновления или удаления данных.
Код:
mutation{
insert_todos(objects:[{title:"Learn GraphQL"}]){
Returning{
Id
Created_at
}
}
}
Например, на скриншоте выше показана мутация, добавляющая новую заметку Todo. В случае успеха он вернет идентификатор и дату создания недавно вставленной заметки Todo.
Некоторые распространенные конечные точки GraphQL:
Трудно перечислить все конечные точки в экземпляре GraphQL, но во многих реализациях используется такая структура, как Appollo. В следующем разделе перечислены общие конечные точки, используемые в реализациях GraphQL:
- /v1/*
- /v2/*
- /beta/*
- /graph
- /graphql
- /graphql/console
- /graphql.php
- /graphiql
- /graphiql.php
Схема GraphQL лежит в основе любой реализации сервера GraphQL. В нем описываются функции, доступные клиентам, которые подключаются к экземпляру GraphQL. Это похоже на план, который клиенты могут узнать, запросив его.
Самоанализ:
Чтобы получить схему, мы можем отправить HTTP-запрос на конечную точку сервера GraphQL с запросом схемы GraphQL. Этот тип HTTP-запроса называется запросом самоанализа GraphQL.
Самоанализ — это основная возможность запрашивать, какие ресурсы доступны в схеме. При самоанализе мы можем увидеть запросы, типы, поля и директивы, которые он поддерживает. К сожалению, запрос самоанализа включен по умолчанию, поэтому его стоит попробовать во время теста на проникновение.
Как отправить запрос на самоанализ?
Запрос самоанализа дает нам подробную информацию о запросах, типах, полях и директивах, которые поддерживаются GraphQL, и по умолчанию мы можем использовать запрос самоанализа для каждого экземпляра GraphQL. Давайте посмотрим на запрос самоанализа в действии.
Шаг 1: Перехватите HTTP-запрос с помощью Burp Suite:
Шаг 2: Отправьте HTTP-запрос на Burp Repeater:
Посмотреть вложение 38323
Шаг 3: Замените тело POST общим запросом самоанализа, чтобы получить всю внутреннюю схему. Для этого мы использовали расширение GraphQL Raider для Burp Suite.
Шаг 4. Запишите схему для сбора конфиденциальных вызовов API.
Пример запроса на самоанализ:
Код:
{"query":"\n query IntrospectionQuery {\r\n __schema {\r\n queryType { name }\r\n mutationType { name }\r\n subscriptionType { name }\r\n types {\r\n ...FullType\r\n }\r\n directives {\r\n name\r\n description\r\n locations\r\n args {\r\n ...InputValue\r\n }\r\n }\r\n }\r\n }\r\n\r\n fragment FullType on __Type {\r\n kind\r\n name\r\n description\r\n fields(includeDeprecated: true) {\r\n name\r\n description\r\n args {\r\n ...InputValue\r\n }\r\n type {\r\n ...TypeRef\r\n }\r\n isDeprecated\r\n deprecationReason\r\n }\r\n inputFields {\r\n ...InputValue\r\n }\r\n interfaces {\r\n ...TypeRef\r\n }\r\n enumValues(includeDeprecated: true) {\r\n name\r\n description\r\n isDeprecated\r\n deprecationReason\r\n }\r\n possibleTypes {\r\n ...TypeRef\r\n }\r\n }\r\n\r\n fragment InputValue on __InputValue {\r\n name\r\n description\r\n type { ...TypeRef }\r\n defaultValue\r\n }\r\n\r\n fragment TypeRef on __Type {\r\n kind\r\n name\r\n ofType {\r\n kind\r\n name\r\n ofType {\r\n kind\r\n name\r\n ofType {\r\n kind\r\n name\r\n ofType {\r\n kind\r\n name\r\n ofType {\r\n kind\r\n name\r\n ofType {\r\n kind\r\n name\r\n ofType {\r\n kind\r\n name\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }\r\n ","variables":null}
Ответ может быть довольно большим и трудным для понимания. Лучший способ понять ответ — визуализировать его. Это можно сделать с помощью инструмента «Вояджер».
Чтобы получить тот же результат, что и выше, выполните запрос на самоанализ цели и вставьте ответ в инструмент «Вояджер». Используя этот метод, злоумышленники могут легко идентифицировать конфиденциальные вызовы API и использовать их.
ОРИГИНАЛЬНАЯ СТАТЬЯ