Introspection GraphQL pubblica: perché è un problema e come disattivarla
L'introspection GraphQL è la query integrata che restituisce lo schema completo della tua API: ogni tipo, campo, argomento e mutation. È essenziale in sviluppo, ma per le API private non dovrebbe essere raggiungibile in produzione. Se resta attiva, è una mappa dell'intera superficie d'attacco del tuo backend.
Che cos'è
Ogni server GraphQL implementa un piccolo insieme di meta-campi, in particolare __schema e __type. Una sola POST a /graphql con `query { __schema { types { name fields { name } } } }` restituisce la definizione completa dei tipi.
Strumenti come GraphiQL, Apollo Sandbox e la UI Playground si basano sull'introspection per l'autocompletamento delle query e per mostrare l'esploratore dello schema. In sviluppo è proprio ciò che vuoi; in produzione, su un'API privata, significa che chiunque al mondo può scaricare la stessa mappa.
Perché è importante
Lo schema rivela i nomi dei tuoi modelli, delle relazioni e di ogni mutation esposta — compresi campi admin, interni e deprecati che non dovevano mai essere scoperti dall'esterno. Gli attaccanti lo usano per costruire un elenco mirato di operazioni da sondare alla ricerca di bypass dell'autenticazione, IDOR e bug di injection.
Anche se ogni campo è autorizzato correttamente, mutation nascoste come refundOrder, impersonateUser o exportBackup non dovrebbero pubblicizzarsi. L'introspection trasforma la fase di ricognizione dell'attaccante da ore di tentativi in una singola richiesta.
Come risolverlo
Disattiva l'introspection quando NODE_ENV è production. Lasciala attiva in locale così il tuo team può ancora esplorare lo schema nella Sandbox.
import { ApolloServer } from "@apollo/server";
const server = new ApolloServer({
typeDefs,
resolvers,
introspection: process.env.NODE_ENV !== "production",
});Yoga ha un plugin dedicato; graphql-http usa una regola di validazione di graphql-js. Entrambi bloccano le query di introspection prima che vengano eseguite.
// 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]
: [];GraphiQL, Playground e Apollo Sandbox servono ad aiutare le persone a esplorare lo schema — non appartengono a un endpoint di produzione pubblico. Proteggili con un controllo di autenticazione o non montarli affatto nella build di produzione.
Disattivare l'introspection è una misura di hardening, non un controllo degli accessi. Ogni campo ha comunque bisogno di un'autorizzazione adeguata a livello di resolver — altrimenti chiunque indovini il nome di un campo può ancora chiamarlo. Considera l'introspection come uno dei livelli, non come l'unico.
FAQ
Nascondere lo schema non è solo security through obscurity?
In parte sì — un attaccante determinato può comunque indovinare i nomi dei campi a forza bruta. Ma vale la pena negare una ricognizione economica e completa. Ogni guida commerciale sulle API GraphQL e il cheat sheet GraphQL di OWASP raccomandano di disattivare l'introspection in produzione.
E per un'API pubblica in cui voglio che gli sviluppatori esplorino lo schema?
Pubblica lo schema in modo deliberato — un file Schema Definition Language, un sito di documentazione, oppure l'introspection disponibile solo dopo l'autenticazione. È molto diverso da una POST anonima che restituisce tutto.
Come lo rileva AppSafe?
AppSafe invia con POST una piccola query di introspection a /graphql e /api/graphql e cerca una risposta __schema con stato 200. Se arriva, la segnala con severità media nella categoria Sicurezza delle API.
La tua app è interessata?
AppSafe controlla questo e decine di altri problemi in un'unica scansione gratuita.
Scansiona la mia app gratisGuide correlate
Configurazione CORS errata: le trappole del wildcard e della riflessione
Consenti ogni origine e qualsiasi sito potrà leggere la tua API.
Pagine di errore dettagliate e stack trace in produzione
Uno stack trace dice agli attaccanti esattamente dove mirare.
Metodi HTTP pericolosi: come vengono annunciati TRACE, PUT e DELETE
Una risposta OPTIONS che elenca TRACE o DELETE rivela più del dovuto.
API key esposte nel JavaScript lato client
Tutto ciò che è nel tuo bundle è pubblico. Trattalo come tale.