Todos os guias
Severidade MédiaSegurança de API

Introspecção pública do GraphQL: por que é um problema e como desativá-la

A introspecção do GraphQL é a query embutida que retorna o schema completo da sua API: cada tipo, campo, argumento e mutation. Ela é essencial em desenvolvimento, mas não deveria estar acessível em produção em APIs privadas. Deixada ativada, ela é um mapa de toda a superfície de ataque do seu backend.

O que é

Todo servidor GraphQL implementa um pequeno conjunto de metacampos, principalmente __schema e __type. Um único POST para /graphql com `query { __schema { types { name fields { name } } } }` retorna a definição completa dos tipos.

Ferramentas como GraphiQL, Apollo Sandbox e a interface Playground dependem da introspecção para autocompletar queries e exibir o explorador do schema. Em desenvolvimento é exatamente isso que você quer; em produção, numa API privada, significa que qualquer pessoa no mundo pode baixar o mesmo mapa.

Por que importa

O schema nomeia os seus models, os seus relacionamentos e cada mutation que você expõe — incluindo campos administrativos, internos e obsoletos que nunca deveriam ser descobertos de fora. Atacantes o usam para montar uma lista direcionada de operações para testar falhas de bypass de autenticação, IDOR e injeção.

Mesmo que todos os campos estejam corretamente autorizados, mutations ocultas como refundOrder, impersonateUser ou exportBackup não deveriam se anunciar. A introspecção transforma a fase de reconhecimento do atacante de horas de tentativa e erro numa única requisição.

Como corrigir

Desative a introspecção no Apollo Server

Desligue a introspecção quando NODE_ENV for production. Mantenha-a ativada localmente para que a sua equipe ainda possa explorar o schema no Sandbox.

import { ApolloServer } from "@apollo/server";

const server = new ApolloServer({
  typeDefs,
  resolvers,
  introspection: process.env.NODE_ENV !== "production",
});
Desative-a no GraphQL Yoga / graphql-http

O Yoga tem um plugin oficial; o graphql-http expõe uma regra de validação do graphql-js. Ambos bloqueiam queries de introspecção antes que sejam executadas.

// GraphQL Yoga
import { createYoga } from "graphql-yoga";
import { useDisableIntrospection } from "@graphql-yoga/plugin-disable-introspection";

export const yoga = createYoga({
  schema,
  plugins: process.env.NODE_ENV === "production" ? [useDisableIntrospection()] : [],
});

// graphql-http (or express-graphql)
import { NoSchemaIntrospectionCustomRule } from "graphql";

const validationRules = process.env.NODE_ENV === "production"
  ? [NoSchemaIntrospectionCustomRule]
  : [];
Remova as interfaces de exploração do schema da produção

GraphiQL, Playground e Apollo Sandbox existem para ajudar pessoas a explorar o schema — eles não têm lugar num endpoint público de produção. Proteja-os com uma verificação de autenticação ou simplesmente não os monte no build de produção.

Prefira autorização a listas de bloqueio

Desativar a introspecção é uma medida de hardening, não controle de acesso. Cada campo ainda precisa de autorização adequada no nível do resolver — caso contrário, qualquer um que adivinhe o nome de um campo ainda consegue chamá-lo. Trate a introspecção como uma camada, não como a única camada.

FAQ

Esconder o schema não é só segurança por obscuridade?

Em parte, sim — um atacante determinado ainda pode descobrir nomes de campos por força bruta. Mas vale a pena não deixar o reconhecimento barato e completo. Todos os guias comerciais de APIs GraphQL e a cheat sheet de GraphQL da OWASP recomendam desativar a introspecção em produção.

E se for uma API pública em que eu quero que desenvolvedores explorem o schema?

Publique o schema de forma deliberada — disponibilize um arquivo em Schema Definition Language, hospede um site de documentação ou exponha a introspecção só depois da autenticação. Isso é muito diferente de um POST anônimo retornar tudo.

Como o AppSafe detecta isso?

O AppSafe envia via POST uma pequena query de introspecção para /graphql e /api/graphql e procura uma resposta __schema com status 200. Se ela voltar, o problema é sinalizado com severidade média na categoria Segurança de API.

Seu app está afetado?

O AppSafe verifica isso e dezenas de outros problemas em um único escaneamento grátis.

Escanear meu app grátis