Mejora la seguridad de GraphQL con análisis estático y Snyk Code
Sam Sanoop
12 de abril de 2022
0 minutos de lecturaGraphQL es un lenguaje de consulta para API desarrollado por Facebook en 2015. Desde entonces, sus características y capacidades únicas lo han convertido en una alternativa viable a las API REST. En cuanto a la seguridad, los servidores GraphQL pueden presentar varios tipos de configuraciones incorrectas que provocan filtraciones de datos, problemas de control de acceso y otras vulnerabilidades de alto riesgo.
Aunque los problemas de seguridad de GraphQL son ampliamente conocidos, hay poca información sobre cómo detectarlos más allá del análisis dinámico. En esta publicación, veremos cómo se manifiestan las vulnerabilidades comunes de GraphQL en una base de código y cómo detectarlas con herramientas de análisis estático y GraphQL Security. Como muchos frameworks de GraphQL de uso extendido están en npm, nos centraremos en ejemplos del ecosistema NodeJS.
Análisis de taint en frameworks de GraphQL
Numerosos estudios sobre endpoints de GraphQL han reportado vulnerabilidades de inyección SQL y deserialización. Un ejemplo puede verse en el informe de HackerOne, donde se presenta una inyección SQL a través de un parámetro de GraphQL.
Al igual que los parámetros de las API REST, los argumentos de GraphQL son una fuente de taint por la que se pueden introducir datos proporcionados por los usuarios en una aplicación. Las herramientas de análisis estático deberían poder identificar y modelar estos parámetros con precisión en una aplicación.
En los frameworks de GraphQL, los resolvers conectan el esquema, la función y los argumentos antes de pasarlos a las funciones resolver. El siguiente ejemplo muestra el argumento args como un objeto que contiene todos los argumentos de GraphQL proporcionados para el campo por la operación de GraphQL.
El motor de Snyk Code puede rastrear estas expresiones args y aprovecha el análisis de puntos a y el análisis de estados de tipo para registrar con precisión la ejecución del programa. El análisis de SonicJS con Snyk Code, un sistema de gestión de contenido moderno y de código abierto basado en NodeJs, es un ejemplo útil.
SonicJS ayuda a los usuarios a realizar operaciones de CMS a través de su endpoint de GraphQL. Una de estas operaciones es la mutación fileUpdate, que permite a un usuario actualizar sus archivos.
Esta consulta de mutación toma la entrada proporcionada por el usuario, llamada args.filePath y args.fileContent, y luego la envía a la función writeFile del objeto fileService. La implementación de la función del objeto fileService está en server/services/file.service.js y se muestra a continuación.
Esta función toma ambos argumentos de GraphQL y usa la función fs.writeFile para actualizar el archivo en la ruta proporcionada. Sin embargo, es posible aprovechar esta función para recorrer el directorio de la aplicación y crear un archivo nuevo en cualquier ubicación del sistema objetivo, como en la siguiente consulta de GraphQL:
Esta vulnerabilidad permite ejecutar código en el sistema al sobrescribir uno de los archivos de servicio de SonicJS con JavaScript malicioso que el sistema de SonicJS carga durante el inicio o el reinicio. Por ejemplo, la siguiente instrucción usa la función child_process para instalar una puerta trasera en la aplicación y conectarse a una dirección IP controlada por un atacante mediante el programa ncat, instalado en el sistema objetivo.

A continuación, se muestra el informe de Snyk Code sobre esta vulnerabilidad:

SonicJS puede prevenir esta vulnerabilidad en el futuro al exigir autenticación y autorización para la consulta, y validar la ruta del archivo proporcionada para asegurarse de que no se permitan caracteres especiales como ../.
Introspección de GraphQL
El sistema de introspección de GraphQL permite descubrir qué consultas admite un servidor de GraphQL. Esto incluye tipos, campos, consultas, mutaciones y otra información relacionada con un esquema de GraphQL.
Aunque esta es una funcionalidad y no representa un problema de seguridad directo, la introspección suele usarse para encontrar funcionalidades ocultas que un atacante puede aprovechar.
En el ecosistema NodeJS, los frameworks de JavaScript suelen habilitar la introspección de forma predeterminada, algo que quizá no sea evidente para los desarrolladores. Por eso, al usar el framework de GraphQL sin especificar ajustes, como en express-graphql a continuación, la introspección se habilita automáticamente.
A continuación, se muestra un ejemplo de este informe en Snyk Code:

Como puede haber casos legítimos en los que se necesite introspección en una aplicación de producción, este problema se reportó como de bajo riesgo.
Para deshabilitar la introspección en express-graphql, usa NoSchemaIntrospectionCustomRule, proporcionado por graphql-js.
Aunque habilitar la introspección en producción puede ocasionar problemas de seguridad, a menudo se necesita durante el desarrollo. Los creadores de ApolloServer abordaron este problema al habilitar o deshabilitar la introspección según el estado de producción.
Si usas otro framework de GraphQL, puedes usar una biblioteca de terceros, como el paquete graphql-disable-introspection, para validar las reglas en tu endpoint de GraphQL.
Denegación de servicio en GraphQL
Cada consulta tiene una profundidad de objetos anidados que un endpoint de GraphQL puede procesar. La mayoría de los frameworks de GraphQL no tienen un límite de profundidad predeterminado. Las consultas sin límite de profundidad pueden dejar al framework vulnerable a ataques de denegación de servicio (DoS), como en el siguiente ejemplo:
Sin embargo, para que se pueda explotar este problema, el servidor de GraphQL debe tener un patrón recursivo de tipos de campo en el que exista una relación bidireccional. A continuación, se muestra un ejemplo de este informe en Snyk Code:

Esta vulnerabilidad de DoS se encontró en mevn-cli. Para corregirla, se puede usar el paquete graphql-depth-limit disponible en npm, como se muestra a continuación:
Revisa este commit del repositorio de mevn-cli para ver un ejemplo de esta corrección.
Otra forma de prevenir los ataques de DoS es revisar la longitud del cuerpo de la solicitud en tu endpoint de GraphQL. Las consultas extensas pueden indicar un ataque de DoS, por lo que monitorear la longitud de las consultas es una verificación sencilla y eficaz.
Inyección de GraphQL
Al permitir que un atacante interfiera con una consulta de la aplicación, una inyección de GraphQL da acceso a partes maliciosas a datos que normalmente no podrían obtener, incluidos datos de usuarios o cualquier otro dato al que pueda acceder la aplicación. En muchos casos, estos datos pueden modificarse o eliminarse, lo que provoca cambios persistentes en el contenido y el comportamiento de la aplicación.
@octokit/core es una biblioteca minimalista diseñada para utilizar las API REST y GraphQL de GitHub y crear consultas de GraphQL. Cuando se usa la entrada del usuario para crear consultas de GraphQL de forma dinámica, un atacante podría modificar la consulta para acceder a información confidencial. A continuación, se muestra un ejemplo de este problema:
A continuación, se muestra un ejemplo de este informe en Snyk Code.

Para prevenir la inyección de GraphQL, evita pasar directamente a una consulta de GraphQL los parámetros ingresados por el usuario. Si necesitas usar directamente la entrada del usuario por motivos de rendimiento, valídala con una lista de permitidos muy estricta de caracteres permitidos. Evita los caracteres especiales como ? & / < > ; - y el espacio, y usa una rutina de escape proporcionada por el proveedor, si es posible.
Conclusión
Actualmente, Snyk Code es compatible con los siguientes frameworks de GraphQL mediante diversas reglas de análisis de taint y semántica:
express-graphqlkoa-graphqlmercuriusapollo-servergraphql-js
Esperamos agregar compatibilidad con otras vulnerabilidades de GraphQL, como referencias directas a objetos inseguros y problemas de control de acceso. Aunque actualmente GraphQL es compatible con JavaScript, nuestro objetivo es agregar más lenguajes de programación y reglas de calidad de código para abordar problemas como los ataques por lotes y la complejidad de las consultas.
Comienza con Capture the Flag
Aprende a resolver desafíos de Capture the Flag con nuestro taller virtual 101 a pedido.


