Security
11 min read
1757 views

Inyección de Subgráfica Federada: La fuga de datos "Ciega" en GraphQL

IT
InstaTunnel Team
Published by our engineering team
Inyección de Subgráfica Federada: La fuga de datos "Ciega" en GraphQL

A medida que las empresas migran agresivamente de arquitecturas monolíticas a Federated GraphQL (Supergraphs), ha surgido una nueva y crítica clase de vulnerabilidad: Inyección de Subgráfica Federada. Mientras las organizaciones refuerzan sus API Gateways, a menudo descuidan la parte más vulnerable de la arquitectura — las subgráficas mismas. Esta vulnerabilidad explota la confianza implícita entre el Gateway y sus subgráficas, permitiendo a los atacantes “coser” fragmentos de datos sensibles de microservicios privados que nunca debieron unirse. Este artículo explora la mecánica del ataque, por qué es invisible para los WAFs tradicionales y cómo implementar una arquitectura de Zero Trust para tu Data Graph.


El auge del Supergraph (y la brecha de seguridad)

En el panorama moderno de APIs, Federation de GraphQL — popularizada por Apollo Federation, Hasura y WunderGraph — se ha convertido en el estándar para unificar docenas de microservicios dispares (sub-gramas) en un único endpoint consultable (el Supergraph o Gateway).

La arquitectura de confianza

En una configuración federada típica:

  1. El usuario envía una consulta al Gateway.
  2. El Gateway valida el JWT del usuario, verifica permisos de alto nivel y construye un Plan de Consulta.
  3. El Gateway divide la consulta en fragmentos y los envía a las sub-gramas respectivas (por ejemplo, Servicio de Usuarios, Servicio de Facturación, Inventario).
  4. Las sub-gramas ejecutan su parte y devuelven JSON.
  5. El Gateway fusiona (“coser”) los resultados y los envía de vuelta al usuario.

El fallo fatal: La mayoría de los equipos de ingeniería tratan las sub-gramas como “internas” y, por tanto, “seguras”. Asumen que si una solicitud llega a una sub-grama, el Gateway ya la ha autorizado. En consecuencia, las sub-gramas a menudo eliminan sus propias verificaciones de autorización, creando un problema clásico de Confused Deputy.


¿Qué es la Inyección de Subgráfica Federada?

La Inyección de Subgráfica Federada es una vulnerabilidad del lado del servidor donde un atacante manipula la estructura de la consulta GraphQL para forzar al Gateway a inyectar fragmentos maliciosos en una sub-grama vulnerable.

Debido a que la sub-grama asume que el Gateway es el único llamante — y que el Gateway es “inteligente” — ejecuta ciegamente solicitudes para campos sensibles (como PII, IDs internos o banderas de administrador) sin verificar si el usuario original realmente tenía permiso para ver esos campos en ese contexto específico.

¿Por qué es “Ciega”?

El término “ciega” se refiere a dos modos de fallo distintos:

Ceguera del Gateway: El Gateway ve una consulta sintácticamente válida. Verifica su esquema global y dice, “Esto parece correcto.” No necesariamente conoce las restricciones de lógica de negocio del microservicio subyacente.

Ceguera de la sub-grama: La sub-grama recibe una solicitud diciendo efectivamente, “Dame el SSN para el Usuario ID 123.” No ve el token o contexto del cliente original — o lo ignora — confiando en la solicitud simplemente porque provino de la IP del Gateway.


Anatomía del ataque

Escenario: La fuga de identidad “Cosida”

Imagina un Supergraph con dos sub-gramas:

  • Sub-grama de Usuarios: Maneja datos de perfil público.
  • Sub-grama de Facturación: Maneja información privada de tarjetas de crédito y facturas.

La sub-grama de Usuarios define:

type User @key(fields: "id") {
  id: ID!
  username: String
  # Solo información pública
}

La sub-grama de Facturación extiende el tipo User:

extend type User @key(fields: "id") {
  id: ID! @external
  last4Digits: String
  invoices: [Invoice]
  # SENSIBLE: Solo el usuario debe ver esto
  internalRiskScore: Int
}

La vulnerabilidad

El Gateway exige que un usuario esté autenticado para consultar invoices. Sin embargo, el campo internalRiskScore en la sub-grama de Facturación carece de una directiva @auth específica porque los desarrolladores asumieron, “Es un campo interno — el Gateway no lo expondrá al esquema público.”

Si la composición del esquema está mal configurada (más sobre ejemplos del mundo real abajo), o si el atacante usa Fragment Injection, puede evitar las verificaciones superficiales del Gateway.

La consulta de explotación

query LeakRiskScore {
  node(id: "User:123") {
    ... on User {
      username
      _onBilling_internalRiskScore: internalRiskScore
    }
  }
}

Flujo de ejecución

  1. Gateway ve una solicitud para un Node. Resuelve el ID.
  2. Planificador de consultas se da cuenta de que internalRiskScore vive en la sub-grama de Facturación.
  3. Inyección: El Gateway genera una solicitud de obtención a la sub-grama de Facturación:
query {
  _entities(representations: [{ __typename: "User", id: "123" }]) {
    ... on User {
      internalRiskScore
    }
  }
}
  1. Sub-grama de Facturación recibe la solicitud. Ve una petición para internalRiskScore con ID 123. No verifica si el usuario actual es el Usuario 123. Asume que ya fue verificado por el Gateway.
  2. Fuga: La sub-grama de Facturación devuelve la puntuación 99 (Alto Riesgo).
  3. Respuesta: El atacante recibe los datos privados.

CVEs reales: Esto ya no es solo teórico

Este patrón de ataque ha avanzado mucho más allá de la teoría. A finales de 2025, se divulgaron múltiples CVEs de alta severidad contra Apollo Federation — el runtime federado de GraphQL más desplegado.

CVE-2025-64530 — Bypass en control de acceso a interfaces (noviembre 2025)

Severidad: Alta

Una vulnerabilidad en la lógica de composición de Apollo Federation (versiones anteriores a 2.9.5, 2.10.4, 2.11.5 y 2.12.1) permitía que las consultas bypassaran controles de acceso en tipos e interfaces. Apollo Federation permitía incorrectamente directivas de control de acceso definidas por el usuario (@authenticated, @requiresScopes, @policy) en tipos de interfaz. Debido a que la especificación GraphQL no define reglas de herencia para directivas de interfaces a sus tipos implementadores, estas directivas no se propagaban a las implementaciones concretas.

Un atacante podía consultar datos protegidos a través del tipo de objeto que implementa usando un fragmento inline o nombrado, saltándose completamente el control en la interfaz. La corrección rechazó directivas de control de acceso definidas por el usuario en tipos de interfaz, generando automáticamente las directivas correctas en las implementaciones.

Mitigación: Actualiza a Apollo Federation composición 2.9.5+, 2.10.4+, 2.11.5+ o 2.12.1+. Si usas una versión sin parches, copia manualmente los requisitos de control de acceso desde las interfaces a cada tipo implementador.

CVE-2025-64173 — Fallo en autorización de tipos polimórficos

Severidad: Alta

En versiones 1.61.11 y anteriores (y 2.0.0-alpha.0 a 2.8.1-rc.0) de Apollo Router Core, el router manejaba incorrectamente las directivas de control de acceso en tipos de interfaz y sus tipos de objeto implementadores. Cuando todas las implementaciones compartían los mismos requisitos, el router aplicaba las directivas en la interfaz ignorando las directivas en los tipos de objeto. Esto permitía consultas no autenticadas acceder a datos que requerían controles adicionales.

Mitigación: Actualiza Apollo Router a 1.61.12 o 2.8.1.

CVE-2025-64347 — Bypass en directiva renombrada

Severidad: Alta

En versiones 1.61.12-rc.0 y anteriores de Apollo Router Core, las directivas de control de acceso renombradas mediante @link no se aplicaban. Si un equipo alias @authenticated a un nombre personalizado en su esquema, el router no aplicaba esa directiva — dejando la campo sin protección. La corrección se lanzó en versiones 1.61.12 y 2.8.1.

GHSA-m8jr-fxqx-8xx6 — Bypass transitorio en control de acceso a campos

Otra vulnerabilidad en la lógica de composición de Apollo Federation no hacía cumplir que los campos que dependen de datos protegidos mediante @requires o @fromContext heredaran los mismos requisitos de control de acceso. Un atacante podía consultar un campo que dependía de un campo protegido sin activar la verificación, ya que solo se solicitaba el campo dependiente — no el campo protegido. La corrección asegura que los campos dependientes coincidan con los requisitos de acceso de los campos que referencian.


Variante del ataque: Exposición directa de sub-gramas (el “Shadow Graph”)

Incluso cuando el Gateway está perfectamente asegurado, muchas organizaciones exponen accidentalmente sus endpoints de sub-gramas (por ejemplo, billing-service.internal:4000/graphql) mediante:

  • Balanceadores de carga mal configurados o controladores de ingreso
  • Vulnerabilidades SSRF en servicios adyacentes
  • Nombres DNS internos predecibles accesibles desde una DMZ

Como señala la propia guía de seguridad de Apollo, cuando las sub-gramas son accesibles directamente, se evita por completo la seguridad del router. La consulta _entities — la consulta especial que usa el Gateway para obtener datos federados — se convierte en un mecanismo de acceso a datos sin autenticación para cualquiera que pueda acceder al endpoint.

Si un atacante puede acceder directamente a la sub-grama, puede simular una solicitud del Gateway:

POST http://billing-service.internal:4000/graphql

{
  "_entities": [{ "__typename": "User", "id": "456" }],
  "query": "query { _entities(representations: [{ __typename: \"User\", id: \"456\" }]) { ... on User { internalRiskScore invoices { amount } } } }"
}

Sin JWT. Sin encabezado de autenticación. Solo acceso interno sin protección.


Por qué los WAFs tradicionales no detectan esto

Un Web Application Firewall (WAF) opera principalmente sobre firmas de solicitudes HTTP — patrones de URL, payloads, cadenas maliciosas conocidas. La inyección de sub-gramas en GraphQL produce:

  • Consultas GraphQL sintácticamente válidas
  • Solicitudes POST /graphql estándar con Content-Type: application/json
  • Sin SQL, comandos shell o payloads de inyección clásicos
  • Solicitudes que “tienen éxito” desde la perspectiva de los logs del Gateway, mostrando una respuesta 200 OK

Esto significa que los logs de acceso del Gateway no muestran anomalías. La brecha es invisible en cada capa, excepto en la sub-grama misma — que, por diseño, no tiene conciencia de que la solicitud fue no autorizada. Este es el núcleo del problema de cumplimiento: un registro de auditoría GDPR o CCPA mostrará una solicitud legítima que devuelve un 200, sin registro de qué campos específicos de la sub-grama fueron realmente devueltos.


Defensa en profundidad: Asegurar el Supergraph

Pasar de “Confianza en el Gateway” a “Zero Trust” requiere controles en cada capa.

1. Autorización a nivel de sub-grama (La regla de oro)

Nunca confiar únicamente en el Gateway para la autorización. Cada sub-grama debe validar de forma independiente quién es el usuario y si puede acceder a un objeto específico.

// En el resolver del sub-grama de Facturación
const resolvers = {
  User: {
    internalRiskScore: async (userEntity, args, context) => {
      // CRÍTICO: Verificar siempre la autorización en el resolver
      if (context.userId !== userEntity.id && !context.isAdmin) {
        throw new AuthenticationError("No autorizado para ver el riesgo");
      }
      return fetchRiskScore(userEntity.id);
    }
  }
};

El objeto de contexto debe ser poblado propagando el JWT original del Gateway al sub-grama en cada solicitud. Esto es innegociable.

2. Comunicación segura Gateway-a-Sub-grama

Las sub-gramas solo deben aceptar solicitudes del Gateway legítimo. Hay dos opciones fuertes:

Mutual TLS (mTLS): La defensa más fuerte. Las sub-gramas solo aceptan conexiones desde un certificado cliente emitido al Gateway. Cualquier solicitud directa — de un atacante o SSRF mal configurado — se rechaza en el handshake TLS.

Solicitudes firmadas con HMAC: El Gateway firma cada solicitud a la sub-grama con un secreto compartido. La sub-grama verifica la firma antes de procesar. Nota: un encabezado estático simple como x-gateway-secret: "valor-fijo" no es suficiente — los secretos se filtran en el código fuente, logs y volcados de entorno.

3. Aislamiento de red — Mantén las sub-gramas internas

Como indica la documentación oficial de seguridad de Apollo, las sub-gramas solo deben ser accesibles desde el Router. Nunca deben ser alcanzables desde internet público, segmentos DMZ o servicios que no sean el Gateway. Aplicar esto a nivel de red (grupos de seguridad, políticas VPC, objetos NetworkPolicy en Kubernetes) — no solo por convención.

4. Desactivar _service y _entities en endpoints públicos

El campo _service expone el SDL (Schema Definition Language) en crudo de la sub-grama. El campo _entities es el punto de entrada para consultas federadas. Si tu arquitectura requiere que una sub-grama sea accesible fuera del Gateway (raro y no recomendable), usa middleware para bloquear estos campos a menos que la solicitud provenga de una IP confiable del Gateway.

5. Parchear y mantener actualizado

Los CVEs anteriores muestran que incluso los runtimes de federación bien diseñados pueden tener fallos en la lógica de composición. Debes:

  • Suscribirte a avisos de seguridad de Apollo Router, Apollo Federation y otras librerías de federación que uses.
  • Ejecutar apollo check y rover subgraph check en tu pipeline CI/CD para detectar regresiones en el control de acceso del esquema antes del despliegue.
  • Usar herramientas como GraphQL Inspector o Apollo GraphOS schema checks para identificar campos públicos que devuelven tipos sensibles.

6. Aplicar control de acceso en dependencias @requires y @fromContext

Siguiendo GHSA-m8jr-fxqx-8xx6, audita tu esquema en busca de campos que usen @requires o @fromContext para depender de datos protegidos. Asegúrate de que esos campos dependientes tengan directivas de control de acceso coincidentes. La librería de composición parcheada lo hará cumplir automáticamente, pero los equipos con versiones antiguas deben auditar manualmente.

7. Análisis de coste de consultas en la sub-grama

Los atacantes también pueden usar inyección federada para ejecutar ataques de denegación de servicio solicitando relaciones federadas profundamente anidadas. Implementa límites de profundidad y análisis de coste en la sub-grama — no solo en el Gateway — para prevenir agotamiento de recursos por consultas maliciosas.


Impacto empresarial y de cumplimiento

Las consecuencias de un ataque exitoso de Inyección de Sub-grama Federada van mucho más allá de la fuga de datos inmediata.

Brecha de datos: PII (emails, IDs, datos financieros) puede ser exfiltrada a través de los límites de microservicios desde servicios que se creían protegidos.

Violaciones de cumplimiento: Como los logs del Gateway muestran un 200 OK para una consulta aparentemente legítima, no hay una pista de auditoría obvia de acceso no autorizado. Las investigaciones GDPR y CCPA pueden encontrar organizaciones incapaces de demostrar que el acceso a campos específicos fue controlado correctamente — incluso si tenían una capa de autenticación en el Gateway.

Daño a la reputación: Las arquitecturas federadas se adoptan precisamente por su escalabilidad. Una brecha en esta capa puede afectar datos en todos los servicios del Supergraph simultáneamente.


Resumen

GraphQL federado ofrece una velocidad de desarrollo inmensa, pero fractura fundamentalmente el perímetro de seguridad tradicional. La Inyección de Subgráfica Federada prospera en la brecha entre el “Smart Gateway” y la “Dumb Sub-graph” — y como demuestran los CVEs divulgados a finales de 2025, incluso la lógica de composición de los principales runtimes de federación puede introducir bypass de control de acceso que son invisibles para las herramientas de seguridad convencionales.

El principio a internalizar es simple: la lógica de autorización debe viajar con los datos, no solo con la solicitud. Los equipos de seguridad deben auditar sus Supergraphs hoy, tratar cada sub-grama como un servicio público desde el punto de vista de autorización, y asegurar que el control de acceso se aplique de forma independiente en cada capa del grafo.

Continue from this article into the most relevant product guides and workflows.

Related Topics

#Federated GraphQL, GraphQL federation security, sub-graph injection, GraphQL supergraph attack, GraphQL data leak, GraphQL authorization bypass, GraphQL gateway trust issue, GraphQL microservices security, GraphQL fragment injection, GraphQL query stitching attack, Apollo Federation security, GraphQL schema stitching risk, GraphQL access control flaw, distributed GraphQL security, GraphQL privilege escalation, GraphQL overfetching attack, GraphQL lateral data access, GraphQL microservice data leak, API federation vulnerability, GraphQL trust boundary failure, GraphQL gateway bypass, subgraph authorization gap, GraphQL policy enforcement, GraphQL security 2026, GraphQL attack chain, GraphQL blind data exfiltration, GraphQL query abuse, GraphQL introspection abuse, GraphQL field-level authorization, GraphQL cross-service data leak, GraphQL fragment abuse, GraphQL directive bypass, GraphQL schema composition risk, GraphQL supergraph misconfiguration, GraphQL zero trust architecture, GraphQL API security testing, GraphQL pentesting, GraphQL red team, GraphQL blue team defense, GraphQL monitoring, GraphQL query allowlist, persisted queries security, GraphQL complexity attack vs injection, GraphQL injection variant, API gateway vs subgraph security, microservices authorization failure, distributed auth flaw, GraphQL RBAC bypass, GraphQL ABAC failure, GraphQL data stitching exploit, GraphQL sensitive field exposure, GraphQL API breach, enterprise GraphQL security, GraphQL threat modeling, GraphQL federation attack surface, secure subgraph design, GraphQL least privilege, GraphQL contract testing security, Apollo Router security, GraphQL mesh security

Keep building with InstaTunnel

Read the docs for implementation details or compare plans before you ship.

Share this article

More InstaTunnel Insights

Discover more tutorials, tips, and updates to help you build better with localhost tunneling.

Browse All Articles