<summary><strong>Aprende hacking en AWS de cero a héroe con</strong><ahref="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
* Si quieres ver a tu **empresa anunciada en HackTricks** o **descargar HackTricks en PDF** revisa los [**PLANES DE SUSCRIPCIÓN**](https://github.com/sponsors/carlospolop)!
* Consigue el [**merchandising oficial de PEASS & HackTricks**](https://peass.creator-spring.com)
* Descubre [**La Familia PEASS**](https://opensea.io/collection/the-peass-family), nuestra colección de [**NFTs**](https://opensea.io/collection/the-peass-family) exclusivos
* **Únete al** 💬 [**grupo de Discord**](https://discord.gg/hRep4RUj7f) o al [**grupo de telegram**](https://t.me/peass) o **sigue** a **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/carlospolopm)**.**
* **Comparte tus trucos de hacking enviando PRs a los repositorios de github de** [**HackTricks**](https://github.com/carlospolop/hacktricks) y [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud).
GraphQL actúa como una alternativa a la API REST. Las API REST requieren que el cliente envíe múltiples solicitudes a diferentes puntos finales de la API para consultar datos de la base de datos del backend. Con GraphQL solo necesitas enviar una solicitud para consultar el backend. Esto es mucho más simple porque no tienes que enviar múltiples solicitudes a la API, una sola solicitud puede ser utilizada para recopilar toda la información necesaria.
A medida que surgen nuevas tecnologías, también lo hacen nuevas vulnerabilidades. Por **defecto** GraphQL no implementa **autenticación**, esto queda en manos del desarrollador para implementarlo. Esto significa que por defecto GraphQL permite a cualquiera consultarla, cualquier información sensible estará disponible para atacantes sin autenticación.
Una vez que encuentres una instancia abierta de GraphQL, necesitas saber **qué consultas admite**. Esto se puede hacer utilizando el sistema de introspección, más detalles se pueden encontrar aquí: [**GraphQL: Un lenguaje de consulta para APIs.**\
A menudo es útil pedir a un esquema GraphQL información sobre qué consultas admite. GraphQL nos permite hacer esto…](https://graphql.org/learn/introspection/)
La herramienta [**graphw00f**](https://github.com/dolevf/graphw00f) es capaz de detectar qué motor de GraphQL se utiliza en un servidor y luego imprime información útil para el auditor de seguridad.
Si envías `query{__typename}` a cualquier punto final de GraphQL, incluirá la cadena `{"data": {"__typename": "query"}}` en algún lugar de su respuesta. Esto se conoce como una consulta universal y es una herramienta útil para sondear si una URL corresponde a un servicio de GraphQL.
La consulta funciona porque cada punto final de GraphQL tiene un campo reservado llamado `__typename` que devuelve el tipo del objeto consultado como una cadena.
GraphQL generalmente admite **GET**, **POST** (x-www-form-urlencoded) y **POST**(json). Aunque por seguridad se recomienda permitir solo json para prevenir ataques CSRF.
Para utilizar la introspección para descubrir información del esquema, consulta el campo `__schema`. Este campo está disponible en el tipo raíz de todas las consultas.
Con esta consulta puedes extraer todos los tipos, sus campos y sus argumentos (y el tipo de los argumentos). Esto será muy útil para saber cómo consultar la base de datos.
Si la introspección está habilitada pero la consulta anterior no se ejecuta, intenta eliminar las directivas `onOperation`, `onFragment` y `onField` de la estructura de la consulta.
Si la introspección está habilitada, puedes usar [**GraphQL Voyager**](https://github.com/APIs-guru/graphql-voyager) para ver en una GUI todas las opciones.
En la introspección puedes encontrar **qué objeto puedes consultar directamente** (porque no puedes consultar un objeto solo porque existe). En la siguiente imagen puedes ver que el "_queryType_" se llama "_Query_" y que uno de los campos del objeto "_Query_" es "_flags_", que también es un tipo de objeto. Por lo tanto, puedes consultar el objeto flag.
Puedes ver que los objetos "_Flags_" están compuestos por **name** y **value**. Entonces puedes obtener todos los nombres y valores de las flags con la consulta:
Si estos objetos no necesitan ningún argumento para buscar, podrías **recuperar toda la información de ellos** simplemente **pidiendo** los datos que quieras. En este ejemplo de Internet podrías extraer los nombres de usuario y contraseñas guardados:
De todos modos, ya sabíamos eso, en la sección [Enumeración Básica](graphql.md#basic-enumeration) se propuso una consulta que nos mostraba toda la información necesaria: `query={__schema{types{name,fields{name, args{name,description,type{name, kind, ofType{name, kind}}}}}}}`
Nota que **descubrí** que podía pedir los **parámetros** "_**user**_" y "_**password**_" porque si intento buscar algo que no existe (`query={user(uid:1){noExists}}`) obtengo este error:
Si puedes buscar por un tipo de cadena, como: `query={theusers(description: ""){username,password}}` y **buscas una cadena vacía****volcará todos los datos**. (_Nota que este ejemplo no está relacionado con el ejemplo de los tutoriales, para este ejemplo supón que puedes buscar usando "**theusers**" por un campo String llamado "**description**"_).
GraphQL es una tecnología relativamente nueva que está empezando a ganar tracción entre startups y grandes corporaciones. Además de la falta de autenticación por defecto, los puntos finales de GraphQL pueden ser vulnerables a otros errores como IDOR.
Para este ejemplo imagina una base de datos con **personas** identificadas por el correo electrónico y el nombre y **películas** identificadas por el nombre y la calificación. Una **persona** puede ser **amiga** de otras **personas** y una persona puede **tener películas**.
En la **introspección** puedes encontrar las **mutaciones****declaradas**. En la siguiente imagen, el "_MutationType_" se llama "_Mutation_" y el objeto "_Mutation_" contiene los nombres de las mutaciones (como "_addPerson_" en este caso):
Para este ejemplo, imagina una base de datos con **personas** identificadas por el correo electrónico y el nombre, y **películas** identificadas por el nombre y la calificación. Una **persona** puede ser **amiga** de otras **personas** y una persona puede **tener películas**.
También puede haber una **mutación** para **crear****personas** (denominada `addPerson` en este ejemplo) con amigos y películas (note que los amigos y películas deben existir antes de crear una persona relacionada con ellos):
Autenticación a través de la API GraphQL con **envío simultáneo de muchas consultas con diferentes credenciales** para verificarla. Es un ataque de fuerza bruta clásico, pero ahora es posible enviar más de un par de usuario/contraseña por solicitud HTTP debido a la característica de lotes de GraphQL. Este enfoque engañaría a las aplicaciones de monitoreo de tasa externa haciéndoles creer que todo está bien y que no hay un bot intentando adivinar contraseñas.
A continuación, puedes encontrar la demostración más simple de una solicitud de autenticación de aplicación, con **3 pares de correo electrónico/contraseña diferentes a la vez**. Obviamente, es posible enviar miles en una sola solicitud de la misma manera:
Como podemos ver en la captura de respuesta, las primeras y terceras solicitudes devolvieron _null_ y reflejaron la información correspondiente en la sección de _error_. La **segunda mutación tenía los datos de autenticación correctos** y la respuesta tiene el token de sesión de autenticación correcto.
Cada vez más **puntos finales de graphql están desactivando la introspección**. Sin embargo, los errores que graphql arroja cuando recibe una solicitud inesperada son suficientes para que herramientas como [**clairvoyance**](https://github.com/nikitastupin/clairvoyance) puedan recrear la mayor parte del esquema.
Además, la extensión de Burp Suite [**GraphQuail**](https://github.com/forcesunseen/graphquail) **observa las solicitudes de la API GraphQL que pasan por Burp** y **construye** un esquema GraphQL interno con cada nueva consulta que ve. También puede exponer el esquema para GraphiQL y Voyager. La extensión devuelve una respuesta falsa cuando recibe una consulta de introspección. Como resultado, GraphQuail muestra todas las consultas, argumentos y campos disponibles para su uso dentro de la API. Para más información [**consulta esto**](https://blog.forcesunseen.com/graphql-security-testing-without-a-schema).
Una buena **lista de palabras** para descubrir [**entidades GraphQL se puede encontrar aquí**](https://github.com/Escape-Technologies/graphql-wordlist?).
### Eludiendo las defensas de introspección de GraphQL <a href="#bypassing-graphql-introspection-defences" id="bypassing-graphql-introspection-defences"></a>
Si no puedes hacer que las consultas de introspección se ejecuten para la API que estás probando, intenta insertar un **carácter especial después de la palabra clave `__schema`**.
Cuando los desarrolladores desactivan la introspección, podrían usar una expresión regular para excluir la palabra clave `__schema` en las consultas. Deberías probar caracteres como **espacios**, **nuevas líneas** y **comas**, ya que son **ignorados** por GraphQL pero no por expresiones regulares defectuosas.
Si esto no funciona, intente ejecutar la sonda sobre un método de solicitud alternativo, ya que la introspección solo puede estar deshabilitada para POST. Pruebe una solicitud GET o una solicitud POST con un tipo de contenido de `x-www-form-urlencoded`.
Si la introspección está deshabilitada, intente mirar el código fuente del sitio web. Las consultas a menudo se cargan previamente en el navegador como bibliotecas de javascript. Estas consultas preescritas pueden revelar información valiosa sobre el esquema y el uso de cada objeto y función. La pestaña `Sources` de las herramientas para desarrolladores puede buscar en todos los archivos para enumerar dónde se guardan las consultas. A veces, incluso las consultas protegidas por el administrador ya están expuestas.
Por lo tanto, como las solicitudes CSRF como las anteriores se envían **sin solicitudes de preflight**, es posible **realizar****cambios** en el GraphQL abusando de un CSRF.
Sin embargo, ten en cuenta que el nuevo valor predeterminado de la cookie para la bandera `samesite` de Chrome es `Lax`. Esto significa que la cookie solo se enviará desde una web de terceros en solicitudes GET.
Ten en cuenta que generalmente es posible enviar la **solicitud****de consulta** también como una **solicitud GET y el token CSRF podría no estar validado en una solicitud GET.**
Además, abusando de un **ataque** [**XS-Search**](../../pentesting-web/xs-search.md) podría ser posible exfiltrar contenido del punto final de GraphQL abusando de las credenciales del usuario.
Modificar las variables de entrada de la consulta podría llevar a que se [filtren](https://hackerone.com/reports/792927) detalles sensibles de la cuenta.
[Encadenar consultas](https://s1n1st3r.gitbook.io/theb10g/graphql-query-authentication-bypass-vuln) juntas puede eludir un sistema de autenticación débil.
En el siguiente ejemplo, puedes ver que la operación es "forgotPassword" y que solo debería ejecutar la consulta forgotPassword asociada con ella. Esto se puede eludir agregando una consulta al final, en este caso agregamos "register" y una variable de usuario para que el sistema registre a un nuevo usuario.
Normalmente, los objetos GraphQL no pueden contener múltiples propiedades con el mismo nombre. Los alias te permiten eludir esta restricción **nombrando explícitamente las propiedades que deseas** que la API devuelva. Puedes usar alias para devolver **múltiples instancias del mismo** tipo de objeto en una sola solicitud.
Aunque los alias están destinados a limitar la cantidad de llamadas a la API que necesitas hacer, también se pueden usar para forzar bruscamente un punto final de GraphQL.
Muchos puntos finales tendrán algún tipo de **limitador de tasa en su lugar para prevenir ataques de fuerza bruta**. Algunos limitadores de tasa funcionan en base al **número de solicitudes HTTP** recibidas en lugar del número de operaciones realizadas en el punto final. Debido a que los alias efectivamente te permiten enviar múltiples consultas en un solo mensaje HTTP, pueden eludir esta restricción.
El ejemplo simplificado a continuación muestra una serie de **consultas con alias que verifican si los códigos de descuento de una tienda son válidos**. Esta operación podría potencialmente eludir la limitación de tasa ya que es una sola solicitud HTTP, aunque podría usarse para verificar un gran número de códigos de descuento a la vez.
* [https://github.com/gsmith257-cyber/GraphCrawler](https://github.com/gsmith257-cyber/GraphCrawler): Kit de herramientas que se puede utilizar para capturar esquemas y buscar datos sensibles, probar la autorización, fuerza bruta en esquemas y encontrar caminos hacia un tipo dado.
* [https://blog.doyensec.com/2020/03/26/graphql-scanner.html](https://blog.doyensec.com/2020/03/26/graphql-scanner.html): Se puede utilizar como independiente o [extensión de Burp](https://github.com/doyensec/inql).
* [https://github.com/swisskyrepo/GraphQLmap](https://github.com/swisskyrepo/GraphQLmap): Se puede utilizar como cliente CLI también para automatizar ataques.
* [https://gitlab.com/dee-see/graphql-path-enum](https://gitlab.com/dee-see/graphql-path-enum): Herramienta que enumera las diferentes formas de alcanzar un tipo dado en un esquema GraphQL.
* [https://github.com/doyensec/inql](https://github.com/doyensec/inql): Extensión de Burp para pruebas avanzadas de GraphQL. El _**Scanner**_ es el núcleo de InQL v5.0, donde puedes analizar un punto final de GraphQL o un archivo de esquema de introspección local. Genera automáticamente todas las posibles consultas y mutaciones, organizándolas en una vista estructurada para tu análisis. El componente _**Attacker**_ te permite ejecutar ataques GraphQL por lotes, lo cual puede ser útil para eludir límites de tasa implementados de manera deficiente.
<summary><strong>Aprende a hackear AWS de cero a héroe con</strong><ahref="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
* Si quieres ver a tu **empresa anunciada en HackTricks** o **descargar HackTricks en PDF** revisa los [**PLANES DE SUSCRIPCIÓN**](https://github.com/sponsors/carlospolop)!
* Consigue el [**merchandising oficial de PEASS & HackTricks**](https://peass.creator-spring.com)
* Descubre [**La Familia PEASS**](https://opensea.io/collection/the-peass-family), nuestra colección de [**NFTs**](https://opensea.io/collection/the-peass-family) exclusivos
* **Únete al** 💬 [**grupo de Discord**](https://discord.gg/hRep4RUj7f) o al [**grupo de telegram**](https://t.me/peass) o **sígueme** en **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/carlospolopm)**.**
* **Comparte tus trucos de hacking enviando PRs a los repositorios de GitHub de** [**HackTricks**](https://github.com/carlospolop/hacktricks) y [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud).