GraphQL Hacking 101: Saldırganın Gözünden Zafiyetler
8 dk okuma Siber Güvenlik / API Güvenliği Enis

GraphQL Hacking 101: Saldırganın Gözünden Zafiyetler

Günümüz uygulamalarında API'lerle haberleşme her zamankinden daha kritik bir hale geldi. Bu ihtiyacı karşılamak için REST gibi köklü çözümlerin yanı sıra GraphQL gibi yeni ve esnek teknolojiler de hayatımıza girdi. Bu yazıda, özellikle GraphQL'e odak...

Günümüz uygulamalarında API'lerle haberleşme her zamankinden daha kritik bir hale geldi. Bu ihtiyacı karşılamak için REST gibi köklü çözümlerin yanı sıra GraphQL gibi yeni ve esnek teknolojiler de hayatımıza girdi. Bu yazıda, özellikle GraphQL'e odaklanacak ve bir bug bounty avcısının, siber güvenlik araştırmacısının ya da bir saldırganın gözünden bu teknolojideki zafiyetlerin nasıl sömürüldüğünü anlamaya çalışacağız. Gelin, bu önemli konuya birlikte bakalım.

Başlamadan önce belirtmek isterim ki, bu yazıdaki tüm örnekler ve ekran görüntüleri kontrollü bir sandbox ortamında, tamamen eğitim amacıyla gerçekleştirilmiştir. Hiçbir canlı sisteme zarar verilmemiştir. Buradaki amacımız saldırgan bir yaklaşımı teşvik etmek değil, tam aksine, saldırganların nasıl düşündüğünü ve hareket ettiğini anlayarak daha güvenli sistemler inşa edebilmektir. Savunmanın ilk adımı, potansiyel saldırı vektörlerini bilmektir.

enis.gif

GraphQL Nedir ve Nerede, Neden Kullanılır?

ayrac.png

GraphQl Nedir?

7402UV0.png

GraphQL, Facebook tarafından geliştirilen ve 2015 yılında açık kaynak olarak sunulan bir sorgu dilidir.

REST API'lere alternatif olarak geliştirilmiş olup, istemcilerin ihtiyaç duydukları verileri daha esnek ve verimli bir şekilde sorgulamalarına olanak tanır.

Temel Özellikler

Esneklik: İstemciler, ihtiyaç duydukları belirli veri parçalarını sorgulayabilirler.

Verimlilik: Tek bir istekle birden fazla kaynaktan veri alınabilir.

Tip Güvenliği: GraphQL şeması, veri türlerini ve ilişkileri tanımlar, bu da istemcilerin hangi verilere erişebileceğini önceden bilmesini sağlar.

aTg2fii.png

GraphQL'in neden önemli olduğunu anlamamız için nerede ve neden kullanıldığını anlamamız gerekiyor.

Bundan dolayı aşağıda yazacağım alanları okumanızı ve anlamlandırmanız için kendi içinizde sorgulamanızı istiyorum.

GraphQL mobil ve web tarafında yaygın bir şekilde kullanılır.

GraphQL, REST API'lerinde istemcilerin genellikle ihtiyaç duymadıkları büyük veri blokları almasının önüne geçerek yalnızca gerekli veri parçalarını çekmelerine olanak tanıdığı için tercih edilir. Ayrıca, farklı kaynaklardan gelen verileri tek bir sorguda birleştirebilmesi, API'lerin self-documenting (kendini belgeleyen) yapısıyla entegrasyonun kolaylaşması, güçlü geliştirici araçları sunması ve istemcilerin verileri belirli parçalara ayırarak sorgulamalarına imkan tanıyarak veri aktarımını ve işleme sürelerini optimize etmesi gibi özellikleriyle öne çıkar.

gQwbQJA.png

Temel Sorgular

ayrac.png

GraphQL, sorguları için genellikle GET ve POST yöntemlerini destekler. Bu sorgulardan biri olan Introspection, şema bilgilerini ortaya çıkarmak için kullanılır ve bir saldırganın hedef sistemin yapısını anlamasına yardımcı olur. Geliştirme aşamasında bu paha biçilmez bir araç olsa da, production (canlı) ortamında aktif bırakıldığında, bir saldırgana tüm API'nin haritasını, olası zayıf noktalarını ve veri yapılarını kendi ellerinizle teslim etmek anlamına gelir. Saldırganın gözünden bakınca, introspection sorguları tam bir keşif hazinesi gibi; API'nin veri türlerini, alanlarını, argümanlarını ve ilişkilerini tanımlayan şemayı ele geçirerek, hassas verilere giden yolları kolayca belirleyebilirsin. Bu sayede, keşif aşamasında etkili saldırılar planlamak çok daha basit hale geliyor, mesela yetkisiz veri çekme veya DoS atakları için. Genellikle geliştiriciler production'da bunu devre dışı bırakmayı atlıyor ya da anonim erişime açık API'lerde kontroller yetersiz kalıyor. Benzer bir sıkıntı Red Hat GraphQL'de CVE-2024-50312 olarak yaşanmış, yetkisiz kullanıcılar şema bilgilerine ulaşabilmiş. Parse Server'daki CVE-2025-53364 ise devre dışı bırakmanın bile bazen yetersiz kaldığını gösteriyor.

Örnek sorgular

Tüm tiplerin adlarını bulmak için:

{__schema{types{name}}}

Ekran görüntüsü 2025-09-10 072310.png

Tüm alanlar ve argümanları listelemek için:

{
  __schema {
    types {
      name
      fields {
        name
        args {
          name
          description
          type {
            name
            kind
          }
        }
      }
    }
  }
}

Ekran görüntüsü 2025-09-10 072859.png

Hataları İnceleme

Hata mesajları, sistem hakkında önemli ipuçları verebilir.

Hata mesajlarını tetiklemek için geçersiz sorgular gönderme:

{olmayanbirdeger}

image (5).jpg

Saldırgan açısından hata inceleme, bilgi sızıntısının kapısını aralıyor; geçersiz sorgularla sunucunun verdiği detaylı mesajlar veritabanı türü, kütüphane versiyonu gibi sırları ortaya döküyor. Bu da daha karmaşık ataklar için mükemmel bir zemin hazırlıyor, örneğin SQL injection'ları test ederken başarıyı hemen görmek gibi. Production'da hata mesajları gizlenmemişse veya geliştirme ayarları canlıya taşınmışsa bu tür sorunlar sık çıkıyor. GitLab'daki CVE-2021-4191, GraphQL API'lerde bilgi sızıntısının kullanıcı bilgilerini nasıl enumerate ettiğinin güzel bir örneği.

Veri Çıkarma

Şemayı ve alanları öğrendikten sonra, veri çıkarma işlemleri yapılabilir. Örneğin, bir "user" nesnesi varsa, değerlerini almak için şu sorgu kullanılabilir:

{
  user(id: "1") {
    id
    name
    email
  }
}

Ekran görüntüsü 2025-09-10 074217.png

Veri çıkarma, introspection sonrası "hasat" aşamasıdır. Saldırgan, şemadan öğrendiği alanları sorgulayarak hassas verileri (e-posta, şifre hash'leri) çeker. Bu, kimlik avı veya daha büyük saldırılar için kullanılır. Örneğin, kullanıcı ID'lerini enumerate ederek (1'den başlayarak artırmak) veritabanı dökümü yapılabilir. Erişim kontrolleri yetersizse, anonim sorgulara izin veriliyorsa veya IDOR zafiyeti varsa bu mümkün olur. Bununla ilgili daha önceden GitLab’da ortaya çıkan CVE-2021-4191 zafiyetini inceleyebilirsiniz.

Saldırı Vektörleri

ayrac.png

Yetkilendirme ve Kimlik Doğrulama (Authorization and Authentication)

GraphQL API'leri, REST API'lerine göre daha ince taneli veri erişim kontrolüne ihtiyaç duyar. Yanlış yapılandırılmış yetkilendirme, kullanıcıların yetkileri dışında verilere erişmesine neden olabilir. Örneğin, konunun öncesinde bahsettiğim sorgu ile kullanıcılara erişmeyi deneyebilirsiniz.

query {
  user(id: "123") {
    id
    username
    email
  }
}

Bu vektör, saldırgan için tam bir yetki yükseltme fırsatı. GraphQL'in esnekliği yüzünden belirli alanlara kontrol koymak zorlaşıyor; böylece saldırgan kendi yetkisi dışındaki verilere, mesela admin e-postalarına ulaşabiliyor. Alan bazlı yetkilendirme eksikse ya da token doğrulama yetersizse, özellikle global auth kullanılmayan sistemlerde bu sorun patlak veriyor. Benzer bir durum GraphQL endpoint'lerinde CVE-2025-31481 ile yaşanmış; Relay node type'ı kullanarak kontrolleri bypass ediyor ve yetkisiz sorgulara yol açıyor.

Batch Querying ve Denial of Service (DoS) Saldırıları

GraphQL, tek bir istekte birden fazla sorgunun yapılmasına izin verir. Bu özellik, saldırganların sunucuyu aşırı yüklemesine neden olabilir.

Yani, sunucuyu daha fazla veri döndürmesine zorlayabilirsiniz.​

query {
  nestedField1 {
    nestedField2 {
      nestedField3 {
        nestedField4 {
          ...
        }
      }
    }
  }
}

Bu tür bir sorgu, sunucunun işleme kapasitesini zorlayarak hizmet reddi saldırısına yol açabilir. Saldırgan açısından batch querying, kaynakları kurutmanın kolay yolu; birden fazla sorguyu tek istekte birleştirerek CPU veya RAM'i bitiriyor, sunucuyu yavaşlatıp çökertiyor. Rakip siteleri offline etmek veya fidye istemek için sık kullanılıyor. Query batching sınırlanmamışsa, rate limiting veya complexity limit yoksa bu ataklar kaçınılmaz. Directus'taki CVE-2024-39895, alan duplikasyonuyla benzer bir DoS'a örnek.

Mass Assignment (Toplu Atama) Saldırıları

GraphQL API'leri, istemcilerin veri yapısını belirlemesine izin verir. Bunu yapmak için genellikle mutation komutlarını kullanırız. Böylece yetkisiz alanlara veri ekleyebiliriz.

mutation {
 updateUser(id: "2", input: {role: "admin"}) {
  id
  name
  role
 }
}

Ekran görüntüsü 2025-09-10 074725.png

Bu sorgu, bir kullanıcının yetkisiz bir şekilde yönetici rolüne yükseltilmesine neden olabilir. Saldırgan için mass assignment, veri manipülasyonunun anahtarı; mutation'larda input'ları doldurarak yetkisiz özellikleri değiştiriyor. Input validation eksikse, whitelist yerine blacklist kullanıldığında bu tür açıklar çıkıyor. Parse Server'daki CVE-2025-53364, schema yüklemede benzer manipülasyonlara yol açıyor.

Injection Saldırıları

GraphQL sorguları, doğrudan veritabanı işlemlerine dönüşür. Bu, SQL enjeksiyonu gibi klasik saldırılara açık olabilir.​

{
  userByUsername(username: "" OR 1=1 --") {
    id
    name
    email
  }
}

Ekran görüntüsü 2025-09-10 074949.png

Injection, saldırganın kod enjekte ederek veritabanını ele geçirme aracı; girdiler sanitize edilmezse SQL/NoSQL komutları sokulup tüm veri dökülebiliyor. Argüman sanitization eksikse veya ORM kullanılmıyorsa bu sorunlar baş gösteriyor. GraphQL-Ruby'deki CVE-2025-27407, untrusted schema yüklemeyle benzer injection'lara örnek.

"Deep Query" (Derin Sorgu) Saldırısı

Derin sorgu saldırısı, kötü niyetli bir kullanıcının çok derin ilişkili sorgular göndererek sunucunun aşırı yüklenmesini sağlar.

{
  userWithFriends(id: "1") {
    name
    friends {
      name
      friends {
        name
        friends {
          name
          friends {
            name
          }
        }
      }
    }
  }
}

Ekran görüntüsü 2025-09-10 075121.png

Deep query, saldırganın recursive sorgularla sunucuyu kilitleme taktiği; ilişkileri derinleştirerek veritabanı yükünü katlıyor. Query depth limit yoksa veya recursive ilişkiler sınırsızsa kaçınılmaz. Apollo Gateway'deki CVE-2025-32031, deeply nested fragments ile pahalı sorgulara yol açıyor.

Over-fetching ve Under-fetching Saldırıları

GraphQL'in en büyük avantajlarından biri, istemcilerin tam olarak ihtiyaç duydukları veriyi alabilmeleridir. Ancak, bu esneklik kötüye kullanılabilir.​

{
  users {
    id
    name
    email
    role
    friends {
      id
      name
      email
      friends {
        name
        email
      }
    }
  }
  blogs {
    id
    title
    content
    author {
      id
      name
      email
      role
    }
  }
}

Bu sorgu, tek bir kullanıcı hakkında çok fazla bilgi çekerek sunucu kaynaklarını tüketebilir. Over-fetching saldırıları, hizmet reddi (DoS) saldırılarına yol açabilir. Saldırgan için over-fetching, fazla veri çekerek kaynakları kurutmanın yolu; sunucuyu yorup DoS veya sızıntı yaratıyor. Complexity limit veya field cost hesaplaması yoksa bu ataklar kolaylaşıyor. Apollo Gateway'deki CVE-2025-32031, derin sorgularla benzer over-fetching'e kapı açıyor.

Stored XSS

Zafiyet, komutların hedef sunucuda kalıcı olarak saklanması ve daha sonra kullanıcıya bir web sayfası olarak sunulmasıdır. Örneğin, bir GraphQL mutation kullanılarak sunucuya saklanan ve daha sonra kullanıcıya gönderilen temizlenmemiş girdiler stored XSS saldırılarına yol açabilir.

mutation {
  createBlog(input: {
    title: "Test Blog"
    content: "<script>alert('XSS Vulnerability!')</script>"
    authorId: "1"
  }) {
    id
    title
    content
  }
}

Ekran görüntüsü 2025-09-10 075418.png

Stored XSS, saldırganın mutation ile script sokup kalıcı enjeksiyon yapması; saklanan kod diğer kullanıcılara sunuluyor, cookie çalma veya session hijacking için kullanılıyor. Input sanitization eksikse, mutation'lar girdiyi doğrudan saklıyorsa çıkıyor. Altair GraphQL client'ındaki CVE-2021-41248, benzer stored XSS'e örnek.

OS Command Injection

Bir mutation veya sorgunun kullanıcı girdilerini bir sistem komutunda kullanması durumunda ortaya çıkabilir. Örneğin, sunucu bir URL'den avatar resmi çekmek için kullanıcı girdilerini shell komutlarına (wget, cURL vb.) dahil ettiğinde, yetersiz doğrulama veya temizleme nedeniyle komut enjeksiyonu gerçekleşebilir.

Ekran görüntüsü 2025-09-10 080237.png

OS command injection, saldırganın girdilerle sistem komutlarını çalıştırma şansı; rm -rf gibi enjekte edip sunucuyu ele geçiriyor. Girdiler doğrudan shell'e geçiriliyorsa ve escaping yoksa çıkıyor. @graphql-tools/git-loader'daki CVE-2021-23326, command injection'a yol açıyor.

Server-Side Request Forgery (SSRF)

Saldırganın kötü niyetli bir GraphQL sorgusu veya mutasyonu sunarak, bir URL'yi değişken veya argüman olarak göndermesiyle gerçekleşebilir. Bu, savunmasız bir sunucu veya sisteme yetkisiz HTTP isteklerinin yapılmasına neden olabilir. Saldırgan için SSRF, dahili ağı taramanın aracı; URL argümanıyla sunucuyu internal kaynaklara zorluyor, cloud metadata çalma veya port scanning için kullanılıyor. URL'ler validate edilmezse, whitelist yoksa, özellikle external fetch mutation'larda çıkıyor. WP-GraphQL'deki CVE-2023-23685, authenticated kullanıcıların SSRF yapmasına izin veriyor.

Ekran görüntüsü 2025-09-10 080353.png

ayrac.png

Yazı boyunca GraphQL'in sunduğu esnekliğin, dikkat edilmediğinde nasıl ciddi güvenlik risklerine yol açabileceğini gördük. Introspection'dan DoS saldırılarına, yetkilendirme atlatma denemelerinden enjeksiyonlara kadar birçok saldırı vektörünü inceledik.

GraphQL, doğru yapılandırıldığında oldukça güçlü bir araç. Ancak her sorgunun, her mutation'un potansiyel bir zafiyet kapısı aralayabileceğini unutmamak gerek. Bu yazıdaki teknikleri kendi testlerinizde başlangıç noktası olarak kullanabilirsiniz. Güvenli kodlamalar.

DİĞER DİLLER