Skip to content

awpmlg/ResearchGraphQL

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

54 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

GraphQL

Оглавление

GraphQL — это язык запросов API, предназначенный для обеспечения эффективной связи между клиентами и серверами. Это позволяет пользователю точно указать, какие данные он хочет получить в ответе, помогая избежать больших объектов ответа и множественных вызовов, которые иногда можно увидеть с помощью REST API.

Службы GraphQL устроены так, что клиенту не нужно знать, где находятся данные. Вместо этого клиенты отправляют запросы на сервер GraphQL, который извлекает данные из соответствующих мест. Поскольку GraphQL не зависит от платформы, его можно реализовать с помощью широкого спектра языков программирования и использовать для взаимодействия практически с любым хранилищем данных.

Схемы GraphQL определяют структуру данных службы, перечисляя доступные объекты (известные как типы), поля и отношения.

С данными, описанными схемой GraphQL, можно манипулировать с помощью трех типов операций:

  • Запросы(Queries) на получение данных;
  • Мутации(Mutations) добавляют, изменяют или удаляют данные;
  • Подписки(Subscriptions) аналогичны запросам, но устанавливают постоянное соединение, с помощью которого сервер может упреждающе передавать данные клиенту в указанном формате.

Все операции GraphQL используют одну и ту же конечную точку и обычно отправляются как запрос POST. Это существенно отличается от API-интерфейсов REST, которые используют конечные точки для конкретных операций в ряде методов HTTP. В GraphQL тип и имя операции определяют способ обработки запроса, а не конечную точку, в которую он отправляется, или используемый метод HTTP.

Службы GraphQL обычно реагируют на операции с объектом JSON в запрошенной структуре.

В GraphQL схема представляет собой контракт между внешним и внутренним интерфейсом службы. Он определяет данные, доступные как ряд типов, используя удобочитаемый язык определения схемы. Затем эти типы могут быть реализованы службой.

Большинство определенных типов являются объектными типами. которые определяют доступные объекты, поля и аргументы, которые у них есть. Каждое поле имеет свой собственный тип, который может быть либо другим объектом, либо скаляром, перечислением, объединением, интерфейсом или пользовательским типом.

#Example schema definition 
type Product { 
    id: ID! 
    name: String! 
    description: String! 
    price: Int 
}

Запросы GraphQL извлекают данные из хранилища данных. Они примерно эквивалентны запросам GET в REST API.

Запросы обычно состоят из следующих ключевых компонентов:

  • Тип операции запроса(query). Технически это необязательно, но рекомендуется, так как явно сообщает серверу, что входящий запрос является запросом;
  • Имя запроса. Это может быть что угодно. Имя запроса указывать необязательно, но рекомендуется, так как оно может помочь при отладке;
  • Структура данных. Это данные, которые должен вернуть запрос;
  • Необязательно, один или несколько аргументов. Они используются для создания запросов, которые возвращают сведения о конкретном объекте (например, «дайте мне имя и описание продукта с идентификатором 123»).
#Example query
query myGetProductQuery { 
    getProduct(id: 123) { 
        name 
        description 
    } 
}

В приведенном выше примере показан запрос с именем myGetProductQuery, который запрашивает поля имени и описания продукта с идентификатором 123.

Обратите внимание, что тип продукта может содержать больше полей в схеме, чем запрошено здесь. Возможность запрашивать только те данные, которые вам нужны, является значительной частью гибкости GraphQL.

Мутации каким-то образом изменяют данные, добавляя, удаляя или редактируя их. Они примерно эквивалентны методам POST, PUT и DELETE REST API.

Как и запросы, мутации имеют тип операции, имя и структуру возвращаемых данных. Однако мутации всегда требуют ввода некоторого типа. Это может быть встроенное значение, но на практике оно обычно предоставляется как переменная.

#Example mutation request 
mutation { 
    createProduct(name: "Flamin' Cocktail Glasses", listed: "yes") { 
        id 
        name
        listed 
    } 
}

#Example mutation response 
{
    "data": {
        "createProduct": { 
            "id": 123, 
            "name": "Flamin' Cocktail Glasses", 
            "listed": "yes" 
        } 
    } 
}

Синтаксис GraphQL включает в себя несколько общих компонентов для запросов и мутаций:

Все типы GraphQL содержат элементы запрашиваемых данных, называемых полями. Когда вы отправляете запрос или мутацию, вы указываете, какие поля вы хотите, чтобы API возвращал. Ответ отражает содержимое, указанное в запросе.

#Request 
query myGetEmployeeQuery { 
    getEmployees { 
        id 
        name { 
            firstname 
            lastname 
        } 
    } 
}

#Response 
{ 
    "data": {
        "getEmployees": [ 
            { 
                "id": 1, 
                "name" {
                    "firstname": "Carlos", 
                    "lastname": "Montoya"
                } 
            }, 
            { 
                "id": 2,
                "name" { 
                    "firstname": "Peter", 
                    "lastname": "Wiener" 
                } 
            }
        ] 
    } 
}

В приведенном выше примере показан запрос для получения сведений об идентификаторах и именах всех сотрудников и связанный с ним ответ. В этом случае запрашиваются поля id, name.firstname и name.lastname.

Аргументы — это значения, которые предоставляются для определенных полей. Аргументы, которые могут быть приняты для типа, определены в схеме.

Когда вы отправляете запрос или мутацию, содержащую аргументы, сервер GraphQL определяет, как ответить на основе его конфигурации. Например, он может возвращать конкретный объект, а не сведения обо всех объектах.

#Example query with arguments 
query myGetEmployeeQuery { 
    getEmployees(id:1) { 
        name { 
            firstname 
            lastname 
        } 
    } 
}

#Response to query 
{ 
    "data": { 
        "getEmployees": [ 
        { 
            "name" { 
                "firstname": Carlos, 
                "lastname": Montoya
            } 
        } 
        ] 
    } 
}

В приведенном выше примере показан запрос getEmployee, который принимает идентификатор сотрудника в качестве аргумента. В этом случае сервер отвечает только сведениями о сотруднике, который соответствует этому идентификатору.

Примечание: Если предоставленные пользователем аргументы используются для прямого доступа к объектам, API GraphQL может быть уязвим для уязвимостей управления доступом, таких как небезопасные прямые ссылки на объекты (IDOR).

Переменные позволяют передавать динамические аргументы вместо того, чтобы иметь аргументы непосредственно в самом запросе.

Запросы на основе переменных используют ту же структуру, что и запросы со встроенными аргументами, но некоторые аспекты запроса берутся из отдельного словаря переменных на основе JSON. Они позволяют повторно использовать общую структуру в нескольких запросах, при этом изменяется только значение самой переменной.

При построении запроса или мутации, в которой используются переменные, вам необходимо:

  • Объявить переменную и тип;
  • Добавить имя переменной в соответствующее место в запросе;
  • Передать ключ и значение переменной из словаря переменных.
#Example query with variable 
query getEmployeeWithVariable($id: ID!) { 
    getEmployees(id:$id) { 
        name { 
            firstname 
            lastname 
        }
    } 
}

Variables: 
{ 
    "id": 1 
}

В приведенном выше примере показан тот же запрос, что и в предыдущем примере, но с идентификатором, переданным как переменная, а не как непосредственная часть строки запроса.

В этом примере переменная объявлена в первой строке с помощью ($id: ID!). ! указывает, что это обязательное поле для данного запроса. Затем он используется в качестве аргумента во второй строке с (id:$id). Наконец, значение самой переменной устанавливается в словаре переменной JSON.

Объекты GraphQL не могут содержать несколько свойств с одинаковыми именами. Например, следующий запрос недействителен, так как он дважды пытается вернуть тип продукта.

#Invalid query 
query getProductDetails { 
    getProduct(id: 1) { 
        id 
        name 
    } 
    getProduct(id: 2) { 
        id 
        name 
    } 
}

Псевдонимы позволяют обойти это ограничение, явно называя свойства, которые должны возвращаться API. Вы можете использовать псевдонимы для возврата нескольких экземпляров одного и того же типа объекта в одном запросе. Это помогает сократить количество необходимых вызовов API.

#Valid query using aliases 
query getProductDetails { 
    product1: getProduct(id: "1") { 
        id 
        name 
    } 
    product2: getProduct(id: "2") { 
        id 
        name 
    } 
}

#Response to query 
{ 
    "data": { 
        "product1": { 
            "id": 1, 
            "name": "Juice Extractor" 
        }, 
        "product2": { 
            "id": 2, 
            "name": "Fruit Overlays" 
        }
    } 
}

В приведенном выше примере запрос использует псевдонимы для указания уникального имени для обоих продуктов. Этот запрос теперь проходит проверку, и детали возвращаются.

Примечание: Использование псевдонимов с мутациями позволяет эффективно отправлять несколько сообщений GraphQL в одном HTTP-запросе.

Фрагменты — это повторно используемые части запросов или мутаций. Они содержат подмножество полей, принадлежащих связанному типу.

После определения их можно включать в запросы или мутации. Если они впоследствии изменяются, это изменение включается в каждый запрос или изменение, вызывающее фрагмент.

#Example fragment 
fragment productInfo on Product { 
    id 
    name 
    listed 
}

#Query calling the fragment 
query { 
    getProduct(id: 1) { 
        ...productInfo 
        stock 
    } 
}

#Response including fragment fields 
{ 
    "data": { 
        "getProduct": { 
            "id": 1, 
            "name": "Juice Extractor", 
            "listed": "no", 
            "stock": 5 
        } 
    } 
}

В приведенном выше примере показан запрос getProduct, в котором сведения о продукте содержатся во фрагменте productInfo.

Подписки — это особый тип запросов. Они позволяют клиентам устанавливать долговременное соединение с сервером, чтобы сервер мог затем отправлять клиенту обновления в режиме реального времени без необходимости постоянного опроса данных. Они в первую очередь полезны для небольших изменений в больших объектах и для функций, требующих небольших обновлений в реальном времени (таких как системы чата или совместное редактирование).

Как и в случае с обычными запросами и мутациями, запрос на подписку определяет форму возвращаемых данных.

Примечание: Подписки обычно реализуются с использованием WebSockets.

Самоанализ — это встроенная функция GraphQL, которая позволяет запрашивать у сервера информацию о схеме. Он обычно используется такими приложениями, как IDE GraphQL и инструментами для создания документации.

Как и в обычных запросах, вы можете указать поля и структуру ответа, который хотите вернуть. Например, вы можете захотеть, чтобы ответ содержал только имена доступных мутаций.

Самоанализ может представлять серьезный риск раскрытия информации, поскольку его можно использовать для доступа к потенциально конфиденциальной информации (например, к описаниям полей) и помочь злоумышленнику узнать, как он может взаимодействовать с API. Лучше всего отключать самоанализ в производственных средах.

Уязвимости GraphQL обычно возникают из-за недостатков реализации и дизайна. Например, функцию самоанализа можно оставить активной, что позволит злоумышленникам запрашивать API, чтобы получить информацию о его схеме.

Атаки GraphQL обычно принимают форму вредоносных запросов, которые могут позволить злоумышленнику получить данные или выполнить несанкционированные действия. Эти атаки могут иметь серьезные последствия, особенно если пользователь может получить права администратора, манипулируя запросами или выполняя атаку CSRF. Уязвимые API-интерфейсы GraphQL также могут привести к проблемам с раскрытием информации

Прежде чем мы сможем протестировать GraphQL API, нам сначала нужно найти его конечную точку. Поскольку API-интерфейсы GraphQL используют одну и ту же конечную точку для всех запросов, это ценная информация.

Примечание: Burp Scanner может автоматически проверять конечные точки GraphQL в рамках сканирования. При обнаружении любых таких конечных точек возникает проблема «GraphQL endpoint found».

Если вы отправляете запрос{__typename} любой конечной точке GraphQL, он будет включать строку {"data": {"__typename": "query"}} где-то в своем ответе. Это называется универсальным запросом и является полезным инструментом для проверки того, соответствует ли URL-адрес службе GraphQL.

Запрос работает, потому что каждая конечная точка GraphQL имеет зарезервированное поле с именем __typename, которое возвращает тип запрашиваемого объекта в виде строки.

Службы GraphQL часто используют аналогичные суффиксы конечных точек. При тестировании конечных точек GraphQL следует отправлять универсальные запросы в следующие места:

  • /graphql
  • /api
  • /api/graphql
  • /graphql/graphql

Если эти общие конечные точки не возвращают ответ GraphQL, вы также можете попробовать добавить /v1 к пути.

Примечание: Службы GraphQL часто отвечают на любой запрос, отличный от GraphQL, с ошибкой «запрос отсутствует» или аналогичной ошибкой.

Следующим шагом в попытке найти конечные точки GraphQL является тестирование с использованием различных методов запроса.

Для рабочих конечных точек GraphQL рекомендуется принимать только запросы POST, которые имеют тип содержимого application/json, так как это помогает защититься от уязвимостей CSRF. Однако некоторые конечные точки могут принимать альтернативные методы, такие как запросы GET или запросы POST, которые используют тип содержимого x-www-form-urlencoded.

Если не получается найти конечную точку GraphQL, отправляя запросы POST на общие конечные точки, можно попробовать повторно отправить универсальный запрос, используя альтернативные методы HTTP.

Как только вы обнаружите конечную точку, вы можете отправить несколько тестовых запросов, чтобы узнать немного больше о том, как она работает. Если конечная точка обеспечивает работу веб-сайта, попробуйте изучить веб-интерфейс в Burp и использовать историю HTTP для проверки отправленных запросов.

Тестирование аргументов запроса — хорошее место для начала тестирования.

Если API использует аргументы для прямого доступа к объектам, он может быть уязвим для уязвимостей управления доступом. Пользователь потенциально может получить доступ к информации, которой у него не должно быть, просто указав аргумент, соответствующий этой информации. Иногда это называют небезопасной прямой ссылкой на объект (IDOR).

Например, следующий запрос запрашивает список товаров для интернет-магазина:

#Example product query 
query { 
    products { 
        id 
        name 
        listed 
    } 
}

Возвращенный список продуктов содержит только перечисленные продукты.

#Example product response 
{ 
    "data": { 
        "products": [ 
            { 
                "id": 1, 
                "name": "Product 1", 
                "listed": true 
            }, 
            { 
                "id": 2, 
                "name": "Product 2", 
                "listed": true 
            }, 
            { 
                "id": 4, 
                "name": "Product 4", 
                "listed": true 
            } 
        ] 
    } 
}

Из этой информации мы можем сделать следующие выводы:

  • Продуктам присваивается последовательный идентификатор;
  • Код продукта 3 отсутствует в списке, возможно, потому, что он был исключен из списка(из-за переменной “listed”).

Запрашивая идентификатор отсутствующего продукта, мы можем получить его детали, даже если он не указан в магазине и не был возвращен исходным запросом продукта.

#Query to get missing product 
query { 
    product(id: 3) { 
        id 
        name 
        listed 
    } 
}

#Missing product response 
{ 
    "data": { 
        "product": { 
            "id": 3, 
            "name": "Product 3", 
            "listed": no 
        } 
    } 
}

Следующим шагом в тестировании API является сбор информации о базовой схеме.

Лучший способ сделать это — использовать запросы самоанализа. Самоанализ — это встроенная функция GraphQL, которая позволяет запрашивать у сервера информацию о схеме.

Самоанализ поможет понять, как можно взаимодействовать с GraphQL API. Он также может раскрывать потенциально конфиденциальные данные, такие как поля описания.

Чтобы использовать самоанализ для обнаружения информации о схеме, нужно запросить поле __schema. Это поле доступно для корневого типа всех запросов.

Как и в обычных запросах, можно указать поля и структуру ответа, который вернется при выполнении запроса самоанализа. Например, можно построить запрос так, чтобы ответ содержал только названия доступных мутаций.

Лучше всего отключать самоанализ в производственных средах, но этот совет не всегда соблюдается.

Можно провести самоанализ, используя следующий простой запрос. Если самоанализ включен, ответ возвращает имена всех доступных запросов.

#Introspection probe request 
{ 
"query": "{__schema{queryType{name}}}" 
}

Примечание: Burp Scanner может автоматически проверять самоанализ во время сканирования. Если он обнаруживает, что самоанализ включен, он сообщает о проблеме «GraphQL introspection enabled».

Следующим шагом является выполнение полного запроса самоанализа к конечной точке, чтобы получить как можно больше информации о базовой схеме.

Приведенный ниже пример запроса возвращает полную информацию обо всех запросах, мутациях, подписках, типах и фрагментах.

query IntrospectionQuery { 
    __schema { 
        queryType {
            name 
        } 
        mutationType {
            name 
        } 
        subscriptionType { 
            name 
        }
         types {
            ...FullType 
        } 
        directives { 
            name 
            description 
            args { 
                ...InputValue 
            } 
            onOperation #Often needs to be deleted to run query 
            onFragment #Often needs to be deleted to run query 
            onField #Often needs to be deleted to run query 
        } 
    } 
} 

fragment FullType on __Type { 
    kind 
    name 
    description 
    fields(includeDeprecated: true) { 
        name 
        description 
        args { 
            ...InputValue 
        } 
        type { 
            ...TypeRef 
        } 
        isDeprecated 
        deprecationReason 
    } 
    inputFields { 
        ...InputValue 
    } 
    interfaces { 
        ...TypeRef 
    } 
    enumValues(includeDeprecated: true) { 
        name 
        description 
        isDeprecated 
        deprecationReason 
    } 
    possibleTypes { 
        ...TypeRef 
    } 
} 
fragment InputValue on __InputValue { 
    name 
    description 
    type { 
        ...TypeRef 
    } 
    defaultValue 
} 
fragment TypeRef on __Type { 
    kind
    name 
    ofType { 
        kind 
        name 
        ofType { 
            kind 
            name 
            ofType { 
                kind 
                name 
            } 
        } 
    }
}

Примечание: Если самоанализ включен, но приведенный выше запрос не выполняется, попробуйте удалить директивы onOperation, onFragment и onField из структуры запроса. Многие конечные точки не принимают эти директивы как часть запроса самоанализа, и вы часто можете добиться большего успеха в самоанализе, удалив их.

Ответы на запросы самоанализа могут быть полны информации, но часто очень длинны и трудны для обработки.

Вы можете более легко просматривать отношения между объектами схемы с помощью визуализатора GraphQL. Это онлайн-инструмент, который берет результаты запроса самоанализа и создает визуальное представление возвращенных данных, включая отношения между операциями и типами.

В качестве альтернативы выполнению запроса на самоанализ вручную и визуализации результатов можно использовать расширение InQL Burp Suite.

InQL — это расширение Burp Suite, которое помогает безопасно проводить аудит API-интерфейсов GraphQL. Когда вы передаете ему URL-адрес (либо путем предоставления активной ссылки на конечную точку, либо путем загрузки файла JSON), он выдает запрос самоанализа, запрашивающий все запросы и мутации, и представляет структурированное представление, упрощающее изучение результатов.

Даже если самоанализ полностью отключен, иногда можно использовать предложения для сбора информации о структуре API.

Предложения — это функция платформы Apollo GraphQL, в которой сервер может предлагать изменения запросов в сообщениях об ошибках. Они обычно используются, когда запрос немного неверен, но все же распознаваем (например, There is no entry for 'productInfo'. Did you mean 'productInformation' instead?).

Из этого можно потенциально получить полезную информацию, поскольку ответ фактически выдает действительные части схемы.

Clairvoyance — это инструмент, который использует предложения для автоматического восстановления всей или части схемы GraphQL, даже если самоанализ отключен. Это значительно сокращает время, необходимое для сбора информации из ответов на предложения.

Вы не можете отключить предложения непосредственно в Apollo. См. этот GitHub для обходного пути.

Примечание: Burp Scanner может автоматически проверять предложения в рамках сканирования. Если найдены активные предложения, Burp Scanner сообщает о проблеме «GraphQL suggestions enabled».

Если вы не можете запустить запросы самоанализа для тестируемого API, попробуйте вставить специальный символ после ключевого слова __schema.

Когда разработчики отключают самоанализ, они могут использовать регулярное выражение для исключения ключевого слова __schema в запросах. Вы должны попробовать такие символы, как пробелы, новые строки и запятые, поскольку они игнорируются GraphQL, но не ошибочным регулярным выражением.

Таким образом, если разработчик исключил только __schema{, то приведенный ниже запрос самоанализа не будет исключен.

#Introspection query with newline 
{ 
    "query": "query{__schema 
    {queryType{name}}}" 
} 

Если это не сработает, попробуйте запустить зонд с помощью альтернативного метода запроса, так как самоанализ можно отключить только через POST. Попробуйте запрос GET или запрос POST с типом содержимого x-www-form-urlencoded.

В приведенном ниже примере показана проверка самоанализа, отправленная через GET с параметрами, закодированными в URL.

# Introspection probe as GET request 
GET /graphql?query=query%7B__schema%0A%7BqueryType%7Bname%7D%7D%7D 

Примечание: Если конечная точка будет принимать запросы самоанализа только через GET, и вы хотите проанализировать результаты запроса с помощью сканера InQL, вам сначала необходимо сохранить результаты запроса в файл. Затем вы можете загрузить этот файл в InQL, где он будет проанализирован как обычно.

Обычно объекты GraphQL не могут содержать несколько свойств с одинаковыми именами. Псевдонимы позволяют обойти это ограничение, явно называя свойства, которые должны возвращаться API. Вы можете использовать псевдонимы для возврата нескольких экземпляров одного и того же типа объекта в одном запросе.

Хотя псевдонимы предназначены для ограничения количества вызовов API, которые вам нужно сделать, их также можно использовать для атак грубой силы(брута) конечной точки GraphQL.

Многие конечные точки будут иметь какой-то ограничитель скорости для предотвращения атак грубой силы. Некоторые ограничители скорости работают на основе количества полученных HTTP-запросов, а не на количестве операций, выполненных на конечной точке. Поскольку псевдонимы эффективно позволяют отправлять несколько запросов в одном HTTP-сообщении, они могут обойти это ограничение.

#Request with aliased queries 
query isValidDiscount($code: Int) { 
    isvalidDiscount(code:$code){ 
        valid 
    } 
    isValidDiscount2:isValidDiscount(code:$code){ 
        valid 
    } 
    isValidDiscount3:isValidDiscount(code:$code){ 
        valid 
    } 
}

В приведенном выше упрощенном примере показана серия запросов с псевдонимами, проверяющих, действительны ли коды скидок магазина. Эта операция потенциально может обойти ограничение скорости, поскольку это один HTTP-запрос, хотя потенциально ее можно использовать для одновременной проверки большого количества кодов скидок.

Уязвимости межсайтовой подделки запросов (CSRF) позволяют злоумышленнику побуждать пользователей выполнять действия, которые они не намерены выполнять. Это делается путем создания вредоносного веб-сайта, который подделывает междоменный запрос к уязвимому приложению.

GraphQL можно использовать в качестве вектора для CSRF-атак, когда злоумышленник создает эксплойт, который заставляет браузер жертвы отправлять вредоносный запрос от имени пользователя-жертвы.

Уязвимости CSRF могут возникать, когда конечная точка GraphQL не проверяет тип содержимого отправленных ей запросов и не реализуются токены CSRF.

Запросы POST, использующие тип содержимого application/json, защищены от подделки, если тип содержимого проверен. В этом случае злоумышленник не сможет заставить браузер жертвы отправить этот запрос, даже если жертва посетит вредоносный сайт.

Однако альтернативные методы, такие как GET или любой запрос с типом содержимого x-www-form-urlencoded, могут быть отправлены браузером и, таким образом, могут сделать пользователей уязвимыми для атак, если конечная точка примет эти запросы. В этом случае злоумышленники могут использовать эксплойты для отправки вредоносных запросов к API.

Примечание: Шаги по построению атаки GraphQL CSRF и доставке эксплойта такие же как и для «обычных» уязвимостей CSRF.

Чтобы предотвратить многие распространенные атаки GraphQL, при развертывании API в рабочей среде выполните следующие действия:

  • Если ваш API не предназначен для использования широкой публикой, отключите в нем самоанализ. Это усложняет злоумышленнику получение информации о том, как работает API, и снижает риск раскрытия нежелательной информации;
  • Для получения информации о том, как отключить самоанализ на платформе Apollo GraphQL, см. эту запись в блоге;
  • Если ваш API предназначен для использования широкой публикой, вам, вероятно, придется оставить включенным самоанализ. Тем не менее, вам следует просмотреть схему API, чтобы убедиться, что она не делает непреднамеренные поля общедоступными;
  • Убедитесь, что предложения отключены. Это не позволяет злоумышленникам использовать Clairvoyance или аналогичные инструменты для сбора информации о базовой схеме. Вы не можете отключить предложения непосредственно в Apollo. См. этот GitHub для обходного пути;
  • Убедитесь, что схема вашего API не предоставляет никаких личных полей пользователя, таких как адреса электронной почты или идентификаторы пользователей.

Иногда можно обойти стандартное ограничение скорости при использовании API GraphQL. Имея это в виду, существуют шаги проектирования, которые вы можете предпринять, чтобы защитить свой API от атак грубой силы. Как правило, это включает в себя ограничение сложности запросов, принимаемых API, и уменьшение возможностей злоумышленников для выполнения атак типа «отказ в обслуживании» (DoS).

Для защиты от атак грубой силы:

  • Ограничьте глубину запросов вашего API. Термин «глубина запроса» относится к количеству уровней вложенности в запросе. Сильно вложенные запросы могут существенно повлиять на производительность и потенциально могут предоставить возможность для DoS-атак, если они будут приняты. Ограничив глубину запроса, которую принимает ваш API, вы можете уменьшить вероятность этого;
  • Настройте лимиты операций. Ограничения операций позволяют настроить максимальное количество уникальных полей, псевдонимов и корневых полей, которые может принять ваш API;
  • Настройте максимальное количество байтов, которое может содержать запрос;
  • Рассмотрите возможность реализации анализа затрат в вашем API. Анализ затрат — это процесс, посредством которого библиотечное приложение определяет стоимость ресурсов, связанных с выполнением запросов, по мере их поступления. Если запрос слишком сложен для выполнения с точки зрения вычислений, API отбрасывает его.

Примечание: Для получения информации о том, как реализовать эти функции в Apollo, см. эту запись в блоге.

Чтобы защититься конкретно от уязвимостей GraphQL CSRF, убедитесь в следующем при разработке своего API:

  • Ваш API принимает запросы только через POST в кодировке JSON;
  • API проверяет, соответствует ли предоставленный контент предоставленному типу контента;
  • API имеет безопасный механизм токенов CSRF.

About

all about GraphQL vulns

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published