* Você trabalha em uma **empresa de segurança cibernética**? Você quer ver sua **empresa anunciada no HackTricks**? ou você quer ter acesso à **última versão do PEASS ou baixar o HackTricks em PDF**? Verifique os [**PLANOS DE ASSINATURA**](https://github.com/sponsors/carlospolop)!
* Descubra [**A Família PEASS**](https://opensea.io/collection/the-peass-family), nossa coleção exclusiva de [**NFTs**](https://opensea.io/collection/the-peass-family)
* **Junte-se ao** [**💬**](https://emojipedia.org/speech-balloon/) [**grupo Discord**](https://discord.gg/hRep4RUj7f) ou ao [**grupo telegram**](https://t.me/peass) ou **siga-me** no **Twitter** [**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/\[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/hacktricks\_live)**.**
* **Compartilhe seus truques de hacking enviando PRs para o** [**repositório hacktricks**](https://github.com/carlospolop/hacktricks) **e** [**repositório hacktricks-cloud**](https://github.com/carlospolop/hacktricks-cloud).
O GraphQL atua como uma alternativa à API REST. As APIs REST exigem que o cliente envie várias solicitações para endpoints diferentes na API para consultar dados do banco de dados do backend. Com o GraphQL, você só precisa enviar uma solicitação para consultar o backend. Isso é muito mais simples porque você não precisa enviar várias solicitações para a API, uma única solicitação pode ser usada para reunir todas as informações necessárias.
À medida que novas tecnologias surgem, novas vulnerabilidades também surgirão. Por **padrão**, o GraphQL **não** implementa **autenticação**, isso fica a cargo do desenvolvedor implementar. Isso significa que, por padrão, o GraphQL permite que qualquer pessoa o consulte, qualquer informação sensível estará disponível para atacantes não autenticados.
Uma vez que você encontre uma instância aberta do GraphQL, você precisa saber **quais consultas ela suporta**. Isso pode ser feito usando o sistema de introspecção, mais detalhes podem ser encontrados aqui: [**GraphQL: Uma linguagem de consulta para APIs.**\
É frequentemente útil perguntar a um esquema GraphQL informações sobre quais consultas ele suporta. O GraphQL nos permite fazer isso...](https://graphql.org/learn/introspection/)
A ferramenta [**graphw00f**](https://github.com/dolevf/graphw00f) é capaz de detectar qual mecanismo do GraphQL é usado em um servidor e, em seguida, imprime algumas informações úteis para o auditor de segurança.
Se você enviar `query{__typename}` para qualquer endpoint do GraphQL, ele incluirá a string `{"data": {"__typename": "query"}}` em algum lugar de sua resposta. Isso é conhecido como uma consulta universal e é uma ferramenta útil para sondar se uma URL corresponde a um serviço GraphQL.
A consulta funciona porque todo endpoint do GraphQL tem um campo reservado chamado `__typename` que retorna o tipo do objeto consultado como uma string.
O GraphQL geralmente suporta **GET**, **POST** (x-www-form-urlencoded) e **POST**(json). Embora, por motivos de segurança, seja recomendado permitir apenas json para evitar ataques CSRF.
Para usar a introspecção para descobrir informações do esquema, consulte o campo `__schema`. Este campo está disponível no tipo raiz de todas as consultas.
Com essa consulta, você pode extrair todos os tipos, seus campos e seus argumentos (e o tipo dos argumentos). Isso será muito útil para saber como consultar o banco de dados.
**Enumerar Esquema do Banco de Dados via Introspecção**
{% hint style="info" %}
Se a introspecção estiver habilitada, mas a consulta acima não funcionar, tente remover as diretivas `onOperation`, `onFragment` e `onField` da estrutura da consulta.
{% endhint %}
```bash
#Full introspection query
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
Se a introspecção estiver habilitada, você pode usar o [**GraphQL Voyager**](https://github.com/APIs-guru/graphql-voyager) para visualizar em uma interface gráfica todas as opções.
Na introspecção, você pode encontrar **qual objeto você pode consultar diretamente** (porque você não pode consultar um objeto apenas porque ele existe). Na imagem a seguir, você pode ver que o "_queryType_" é chamado "_Query_" e que um dos campos do objeto "_Query_" é "_flags_", que também é um tipo de objeto. Portanto, você pode consultar o objeto flag.
Você pode ver que os objetos "_Flags_" são compostos por **nome** e **valor**. Então você pode obter todos os nomes e valores das flags com a consulta:
Se esses objetos não precisam de nenhum argumento para pesquisar, é possível **recuperar todas as informações deles** apenas **solicitando** os dados desejados. Neste exemplo da Internet, você pode extrair os nomes de usuário e senhas salvos:
Parece que de alguma forma ele fará a pesquisa usando o argumento "_**uid**_" do tipo _**Int**_.\
De qualquer forma, já sabíamos disso, na seção [Enumeração Básica](graphql.md#enumeração-básica) foi proposta uma consulta que mostrava todas as informações necessárias: `query={__schema{types{name,fields{name, args{name,description,type{name, kind, ofType{name, kind}}}}}}}`
Observe que **descobri** que poderia solicitar os **parâmetros** "_**user**_" e "_**password**_" porque se eu tentar procurar algo que não existe (`query={user(uid:1){noExists}}`) recebo este erro:
Se você pode pesquisar por um tipo de string, como: `query={theusers(description: ""){username,password}}` e você **procura por uma string vazia**, ele irá **despejar todos os dados**. (_Observe que este exemplo não está relacionado com o exemplo dos tutoriais, para este exemplo suponha que você possa pesquisar usando "**theusers**" por um campo de String chamado "**description**"_).
GraphQL é uma tecnologia relativamente nova que está começando a ganhar destaque entre startups e grandes corporações. Além da falta de autenticação por padrão, os endpoints do GraphQL podem ser vulneráveis a outros bugs, como IDOR.
Para este exemplo, imagine um banco de dados com **pessoas** identificadas pelo e-mail e pelo nome e **filmes** identificados pelo nome e pela classificação. Uma **pessoa** pode ser **amiga** de outras **pessoas** e uma pessoa pode **ter filmes**.
Na **introspecção**, você pode encontrar as **mutações declaradas**. Na imagem a seguir, o "_MutationType_" é chamado de "_Mutation_" e o objeto "_Mutation_" contém os nomes das mutações (como "_addPerson_" neste caso):
Para este exemplo, imagine um banco de dados com **pessoas** identificadas pelo email e nome, e **filmes** identificados pelo nome e classificação. Uma **pessoa** pode ser **amiga** de outras **pessoas** e uma pessoa pode **ter filmes**.
Também pode haver uma **mutação** para **criar****pessoas** (chamada `addPerson` neste exemplo) com amigos e arquivos (observe que os amigos e filmes devem existir antes de criar uma pessoa relacionada a eles):
Essa informação foi retirada de [https://lab.wallarm.com/graphql-batching-attack/](https://lab.wallarm.com/graphql-batching-attack/).\
Autenticação por meio da API GraphQL com o envio simultâneo de várias consultas com credenciais diferentes para verificá-las. É um ataque clássico de força bruta, mas agora é possível enviar mais de um par de login/senha por solicitação HTTP devido ao recurso de agrupamento do GraphQL. Essa abordagem enganaria aplicativos externos de monitoramento de taxa, fazendo-os pensar que está tudo bem e que não há um robô de força bruta tentando adivinhar senhas.
Abaixo você pode encontrar a demonstração mais simples de uma solicitação de autenticação do aplicativo, com **3 pares de email/senha diferentes de uma vez**. Obviamente, é possível enviar milhares em uma única solicitação da mesma maneira:
Como podemos ver na captura de tela da resposta, as primeiras e terceiras solicitações retornaram _null_ e refletiram as informações correspondentes na seção de _error_. A **segunda mutação tinha os dados de autenticação corretos** e a resposta continha o token de sessão de autenticação correto.
Cada vez mais, **os pontos de extremidade do GraphQL estão desabilitando a introspecção**. No entanto, os erros que o GraphQL gera quando recebe uma solicitação inesperada são suficientes para que ferramentas como [**clairvoyance**](https://github.com/nikitastupin/clairvoyance) possam recriar a maior parte do esquema.
Além disso, a extensão do Burp Suite [**GraphQuail**](https://github.com/forcesunseen/graphquail) **observa as solicitações da API GraphQL que passam pelo Burp** e **constrói** um **esquema** interno do GraphQL com cada nova consulta que ele encontra. Ele também pode expor o esquema para GraphiQL e Voyager. A extensão retorna uma resposta falsa quando recebe uma consulta de introspecção. Como resultado, o GraphQuail mostra todas as consultas, argumentos e campos disponíveis para uso na API. Para mais informações, [**verifique isso**](https://blog.forcesunseen.com/graphql-security-testing-without-a-schema).
### Bypassando as defesas de introspecção do GraphQL <a href="#bypassing-graphql-introspection-defences" id="bypassing-graphql-introspection-defences"></a>
Se você não consegue executar consultas de introspecção na API que está testando, tente inserir um **caractere especial após a palavra-chave `__schema`**.
Quando os desenvolvedores desabilitam a introspecção, eles podem usar uma expressão regular para excluir a palavra-chave `__schema` nas consultas. Você deve tentar caracteres como **espaços**, **quebras de linha** e **vírgulas**, pois eles são **ignorados** pelo GraphQL, mas não pela expressão regular com falhas.
Portanto, se o desenvolvedor tiver excluído apenas `__schema{`, a consulta de introspecção abaixo não será excluída.
```bash
#Introspection query with newline
{
"query": "query{__schema
{queryType{name}}}"
}
```
Se isso não funcionar, tente executar a sonda usando um método de solicitação alternativo, pois a introspecção pode estar desativada apenas para POST. Tente uma solicitação GET ou uma solicitação POST com um tipo de conteúdo `x-www-form-urlencoded`.
### Estruturas GraphQL Vazadas
Se a introspecção estiver desativada, tente analisar o código-fonte do site. As consultas geralmente são pré-carregadas no navegador como bibliotecas JavaScript. Essas consultas pré-escritas podem revelar informações poderosas sobre o esquema e o uso de cada objeto e função. A guia `Sources` das ferramentas de desenvolvedor pode pesquisar todos os arquivos para enumerar onde as consultas estão salvas. Às vezes, até mesmo as consultas protegidas pelo administrador já estão expostas.
Portanto, como as solicitações CSRF como as anteriores são enviadas **sem solicitações de preflight**, é possível **realizar****alterações** no GraphQL abusando de um CSRF.
No entanto, observe que o novo valor padrão do cookie para a flag `samesite` no Chrome é `Lax`. Isso significa que o cookie só será enviado por um site de terceiros em solicitações GET.
Observe também que geralmente é possível enviar a **solicitação de consulta** também como uma solicitação **GET** e o token CSRF pode não ser validado em uma solicitação GET.
Além disso, abusando de um [**ataque XS-Search**](../../pentesting-web/xs-search.md), pode ser possível extrair conteúdo do ponto de extremidade GraphQL abusando das credenciais do usuário.
Modificar as variáveis de entrada da consulta pode levar à **exposição** de detalhes sensíveis da conta [vazada](https://hackerone.com/reports/792927).
[Encadeando consultas](https://s1n1st3r.gitbook.io/theb10g/graphql-query-authentication-bypass-vuln) é possível contornar um sistema de autenticação fraco.
No exemplo abaixo, podemos ver que a operação é "forgotPassword" e que ela deve executar apenas a consulta "forgotPassword" associada a ela. Isso pode ser contornado adicionando uma consulta ao final, neste caso, adicionamos "register" e uma variável de usuário para o sistema registrar como um novo usuário.
Normalmente, objetos GraphQL não podem conter várias propriedades com o mesmo nome. Os aliases permitem contornar essa restrição **nomeando explicitamente as propriedades que você deseja** que a API retorne. Você pode usar aliases para retornar **múltiplas instâncias do mesmo** tipo de objeto em uma única solicitação.
Para obter mais informações sobre aliases no GraphQL, consulte [Aliases](https://portswigger.net/web-security/graphql/what-is-graphql#aliases).
Embora os aliases sejam destinados a limitar o número de chamadas de API que você precisa fazer, eles também podem ser usados para forçar bruta em um ponto de extremidade GraphQL.
Muitos pontos de extremidade terão algum tipo de **limitador de taxa para evitar ataques de força bruta**. Alguns limitadores de taxa funcionam com base no **número de solicitações HTTP** recebidas, em vez do número de operações realizadas no ponto de extremidade. Como os aliases permitem efetivamente enviar várias consultas em uma única mensagem HTTP, eles podem contornar essa restrição.
O exemplo simplificado abaixo mostra uma série de **consultas com aliases verificando se os códigos de desconto da loja são válidos**. Essa operação pode potencialmente contornar o limite de taxa, pois é uma única solicitação HTTP, mesmo que possa ser usada para verificar um grande número de códigos de desconto de uma só vez.
* [https://github.com/gsmith257-cyber/GraphCrawler](https://github.com/gsmith257-cyber/GraphCrawler): Conjunto de ferramentas que pode ser usado para obter esquemas e procurar por dados sensíveis, testar autorização, forçar esquemas e encontrar caminhos para um determinado tipo.
* [https://blog.doyensec.com/2020/03/26/graphql-scanner.html](https://blog.doyensec.com/2020/03/26/graphql-scanner.html): Pode ser usado como um aplicativo independente ou [extensão do Burp](https://github.com/doyensec/inql).
* [https://github.com/swisskyrepo/GraphQLmap](https://github.com/swisskyrepo/GraphQLmap): Pode ser usado como um cliente CLI também para automatizar ataques.
* [https://gitlab.com/dee-see/graphql-path-enum](https://gitlab.com/dee-see/graphql-path-enum): Ferramenta que lista as diferentes maneiras de alcançar um determinado tipo em um esquema GraphQL.
* Você trabalha em uma **empresa de segurança cibernética**? Gostaria de ver sua **empresa anunciada no HackTricks**? Ou gostaria de ter acesso à **última versão do PEASS ou baixar o HackTricks em PDF**? Verifique os [**PLANOS DE ASSINATURA**](https://github.com/sponsors/carlospolop)!
* Descubra [**A Família PEASS**](https://opensea.io/collection/the-peass-family), nossa coleção exclusiva de [**NFTs**](https://opensea.io/collection/the-peass-family)
* Adquira o [**swag oficial do PEASS & HackTricks**](https://peass.creator-spring.com)
* **Junte-se ao** [**💬**](https://emojipedia.org/speech-balloon/) [**grupo Discord**](https://discord.gg/hRep4RUj7f) ou ao [**grupo telegram**](https://t.me/peass) ou **siga-me** no **Twitter** [**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/\[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/hacktricks\_live)**.**
* **Compartilhe seus truques de hacking enviando PRs para o** [**repositório hacktricks**](https://github.com/carlospolop/hacktricks) **e para o** [**repositório hacktricks-cloud**](https://github.com/carlospolop/hacktricks-cloud).