
AppSec दृष्टिकोण से GraphQL पर अनुसंधान।
विभिन्न समस्याओं का अध्ययन करने के लिए एक प्रयोगशाला बनाई गई है, यह कुत्तों की स्वास्थ्य देखभाल करने वाले पशु चिकित्सालय के संदर्भ में है।
प्रयोगशाला को IntelliJ IDEA Community Edition का उपयोग करके विकसित किया गया था।
उपयोग किए गए डोमेन निम्नलिखित हैं:```text
127.0.0.1 localhost 127.0.0.1 domain1.local 127.0.0.1 domain2.local
प्रयोगशाला की शर्तें और धारणाएँ इस प्रकार हैं:
* एक पशुचिकित्सक (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" } }
मैं प्राप्त एक्सेस टोकन का उपयोग करके क्वेरी `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" }, ...
#### 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 क्वेरी बनाने के लिए स्ट्रिंग संयोजन में किया जाता है।
**उदाहरण:**