Saltar a contenido

Circular Fragment in GraphQL

Fragmento circular en GraphQL

Descripción

Los fragmentos circulares en GraphQL se refieren a una situación en la que los fragmentos de las consultas de GraphQL se hacen referencia entre sí, lo que provoca una referencia circular. Esto puede causar problemas como bucles infinitos, agotamiento de recursos y ataques de denegación de servicio (DoS). Un atacante podría aprovechar esto para sobrecargar el servidor GraphQL, haciendo que no esté disponible o que sea lento para los usuarios legítimos.

Impacto en la seguridad de los fragmentos circulares en GraphQL:

1. Denegación de servicio (DoS): Las referencias de fragmentos circulares pueden hacer que el servidor resuelva consultas interminablemente, consumiendo recursos excesivos y, eventualmente, fallando o ralentizándose. 2. Agotamiento de recursos: Los bucles infinitos de fragmentos pueden provocar un alto uso de la CPU y la memoria, causando un agotamiento de los recursos que degrada el rendimiento de la aplicación o el servidor. 3. Explotación de la complejidad de las consultas: Los atacantes pueden diseñar consultas complejas con fragmentos circulares para aprovechar la falta de límites de profundidad o de recursividad en el servidor GraphQL.

Un ejemplo básico de un fragmento circular podría verse así:

fragment UserFields on User {
  name
  ...MoreUserFields
}

fragment MoreUserFields on User {
  email
  ...UserFields
}

En este ejemplo, UserFields hace referencia a MoreUserFields y MoreUserFields hace referencia a UserFields, creando así una referencia circular.

Recomendación

Para mitigar el riesgo de los fragmentos circulares en GraphQL, considere los siguientes pasos:

1. Detección de fragmentos circulares mediante análisis de esquemas

Implemente un análisis estático en su esquema y consultas de GraphQL para detectar y prevenir referencias circulares antes de que puedan ser explotadas. Algunas bibliotecas de servidores GraphQL proporcionan herramientas para analizar esquemas.

  • Tooling: Utilice herramientas de "linting" de GraphQL, como GraphQL Code Generator o GraphQL Inspector, para detectar fragmentos circulares y evitar que lleguen a producción.

Ejemplo usando GraphQL Code Generator:

npm install @graphql-codegen/cli
npx graphql-codegen init

Puede configurar el generador de código para que emita validaciones de esquemas que detecten posibles problemas de fragmentos circulares en sus consultas GraphQL.

2. Implementar el análisis del coste de las consultas

Utilice el análisis de la complejidad de las consultas para asignar un "coste" a cada campo, fragmento o consulta. Cuando una consulta o fragmento excede un umbral de coste predefinido, se puede rechazar automáticamente.

  • Tooling: Puede usar bibliotecas como graphql-query-complexity para calcular el coste de las consultas y limitar el impacto de los fragmentos circulares.

Ejemplo en JavaScript usando graphql-query-complexity:

const { getComplexity, simpleEstimator } = require('graphql-query-complexity');

const server = new ApolloServer({
  schema,
  validationRules: [
    queryComplexity({
      estimators: [
        simpleEstimator({ defaultComplexity: 1 })
      ],
      maximumComplexity: 1000,  // Queries that exceed this complexity will be rejected
      onComplete: (complexity) => {
        console.log('Query Complexity:', complexity);
      },
    }),
  ],
});

3. Imponer límites de profundidad y recursividad

Algunas implementaciones de servidores GraphQL le permiten definir límites para la profundidad y la recursividad de las consultas a fin de evitar el agotamiento de los recursos. Esto ayuda a prevenir bucles infinitos causados por fragmentos circulares.

  • Tooling: Apollo Server, por ejemplo, admite límites de profundidad de consultas, lo que puede prevenir una recursividad excesiva.

Ejemplo de uso del límite de profundidad de consultas en Apollo Server:

const { ApolloServer } = require('apollo-server');
const depthLimit = require('graphql-depth-limit');

const server = new ApolloServer({
  schema,
  validationRules: [depthLimit(5)],  // Set query depth limit to 5
});

4. Usar los fragmentos de manera inteligente

Evite abusar de los fragmentos en consultas complejas. Su uso excesivo puede conducir a una degradación del rendimiento y abre la posibilidad a referencias circulares. En cambio, considere dividir las consultas complejas en múltiples consultas más pequeñas.

  • Recommendation: Revise el diseño de la consulta y limite el uso de fragmentos a elementos de datos modulares y específicos.

Ejemplo:

query {
  user(id: "1") {
    name
    email
    posts {
      title
      content
    }
  }
}

En lugar de anidar múltiples fragmentos entre sí, use una consulta más sencilla como esta.

Enlaces

Estándares

  • CWE_TOP_25:
    • CWE_400
  • PCI_STANDARDS:
    • REQ_6_2
    • REQ_6_4
    • REQ_11_3
  • OWASP_MASVS_L2:
    • MSTG_PLATFORM_2
  • OWASP_ASVS_L3:
    • V13_4_1
  • SOC2_CONTROLS:
    • CC_2_1
    • CC_4_1
    • CC_7_1
    • CC_7_2
    • CC_7_4
    • CC_7_5
    • CC_9_1
  • HIPAA_CONTROLS:
    • SECURITY212
    • SECURITY213