Herkese açık GraphQL introspection: neden sorun ve nasıl kapatılır
GraphQL introspection, API'nin tüm şemasını döndüren yerleşik sorgudur: her tip, alan, argüman ve mutation. Geliştirmede vazgeçilmezdir, ancak özel API'ler için production'da erişilebilir olmamalıdır. Açık bırakılırsa, tüm backend saldırı yüzeyinin bir haritası olur.
Nedir
Her GraphQL sunucusu küçük bir meta-alan kümesi uygular; bunların en önemlileri __schema ve __type'tır. /graphql'e `query { __schema { types { name fields { name } } } }` içeren tek bir POST, tip tanımlarının tamamını döndürür.
GraphiQL, Apollo Sandbox ve Playground UI gibi araçlar, sorguları otomatik tamamlamak ve şema gezginini render etmek için introspection'a dayanır. Geliştirmede istediğin tam olarak budur; production'da, özel bir API'de ise dünyadaki herkesin aynı haritayı indirebileceği anlamına gelir.
Neden önemli
Şema; modellerini, ilişkilerini ve açığa çıkardığın her mutation'ı adlandırır — dışarıdan keşfedilmesi hiç amaçlanmamış admin, dahili ve kullanımdan kaldırılmış alanlar dahil. Saldırganlar bunu, auth bypass, IDOR ve injection hatalarını yoklamak için hedefli bir işlem listesi oluşturmakta kullanır.
Her alan doğru şekilde yetkilendirilmiş olsa bile refundOrder, impersonateUser veya exportBackup gibi gizli mutation'lar kendilerini ilan etmemelidir. Introspection, saldırganın keşif aşamasını saatlerce tahminden tek bir isteğe indirir.
Nasıl düzeltilir
NODE_ENV production olduğunda introspection'ı kapat. Ekibinin şemayı Sandbox'ta keşfetmeye devam edebilmesi için yerelde açık tut.
import { ApolloServer } from "@apollo/server";
const server = new ApolloServer({
typeDefs,
resolvers,
introspection: process.env.NODE_ENV !== "production",
});Yoga'nın birinci sınıf bir plugin'i var; graphql-http ise graphql-js'ten bir doğrulama kuralı kullanır. İkisi de introspection sorgularını çalışmadan önce durdurur.
// 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 ve Apollo Sandbox, insanların şemayı keşfetmesine yardımcı olmak için vardır — herkese açık bir production endpoint'inde yerleri yoktur. Onları bir auth kontrolünün arkasına al ya da production build'inde hiç mount etme.
Introspection'ı kapatmak bir sertleştirme adımıdır, erişim kontrolü değil. Her alanın resolver seviyesinde hâlâ düzgün yetkilendirmeye ihtiyacı vardır — aksi halde bir alan adını tahmin eden herkes onu yine çağırabilir. Introspection'ı tek katman olarak değil, katmanlardan biri olarak gör.
SSS
Şemayı gizlemek sadece gizlilik yoluyla güvenlik değil mi?
Kısmen evet — kararlı bir saldırgan alan adlarını yine de brute-force ile bulabilir. Ama keşfi ucuz ve eksiksiz hale getirmek engellenmeye değer. Tüm ticari GraphQL API rehberleri ve OWASP GraphQL cheat sheet, production'da introspection'ın kapatılmasını önerir.
Geliştiricilerin şemayı keşfetmesini istediğim herkese açık bir API ne olacak?
Şemayı bilinçli olarak yayınla — bir Schema Definition Language dosyası yayınla, bir dokümantasyon sitesi barındır veya introspection'ı yalnızca kimlik doğrulamadan sonra aç. Bu, her şeyi döndüren anonim bir POST'tan çok farklıdır.
AppSafe bunu nasıl tespit ediyor?
AppSafe, /graphql ve /api/graphql'e küçük bir introspection sorgusu POST eder ve 200 durum koduyla bir __schema yanıtı arar. Yanıt gelirse, API Güvenliği kategorisinde orta önem derecesiyle işaretlenir.
Uygulaman etkileniyor mu?
AppSafe, bunu ve onlarca başka sorunu tek bir ücretsiz taramada kontrol eder.
Uygulamamı ücretsiz taraİlgili rehberler
CORS yanlış yapılandırması: joker ve yansıtma tuzakları
Her origin'e izin ver, her site API'ni okuyabilir.
Production'da ayrıntılı hata sayfaları ve stack trace'ler
Bir stack trace, saldırganlara tam olarak nereye nişan alacaklarını söyler.
Tehlikeli HTTP yöntemleri: TRACE, PUT ve DELETE nasıl duyurulur
TRACE veya DELETE listeleyen bir OPTIONS yanıtı olması gerekenden fazlasını açığa çıkarır.
İstemci tarafı JavaScript'te açığa çıkan API key'leri
Bundle'ındaki her şey herkese açıktır. Öyle davran.