
في الآونة الأخيرة ، اكتسبت GraphQL المزيد والمزيد من الشعبية ، ومعها اهتمام متزايد من خبراء أمن المعلومات. تستخدم هذه التكنولوجيا شركات مثل: Facebook و Twitter و PayPal و Github وغيرها ، مما يعني أن الوقت قد حان لمعرفة كيفية اختبار واجهة برمجة التطبيقات هذه. في هذه المقالة ، سنتحدث عن مبادئ لغة الاستعلام هذه وتوجيهات اختبار تغلغل التطبيقات باستخدام GraphQL.
لماذا تحتاج إلى معرفة GraphQL؟ تتطور لغة الاستعلام هذه بشكل نشط ، وهناك المزيد والمزيد من الشركات التي تجد الاستخدام العملي لها. في إطار برامج Bug Bounty ، تزداد شعبية هذه اللغة أيضًا ، ويمكن رؤية أمثلة مثيرة للاهتمام
هنا ،
هنا وهنا .
تدريبموقع اختبار حيث ستجد معظم الأمثلة في هذه المقالة.
قائمة بالتطبيقات التي يمكنك استخدامها أيضًا للدراسة.
للتفاعل مع واجهات برمجة التطبيقات المختلفة ، من الأفضل استخدام GraphQL IDE:
نوصي IDE الأخير: الأرق لديه واجهة مريحة وبسيطة ، وهناك العديد من الإعدادات والإكمال التلقائي لحقول الطلب.
قبل الانتقال مباشرة إلى الأساليب العامة لتحليل أمان التطبيقات باستخدام GraphQL ، نذكر المفاهيم الأساسية.
ما هو GraphQL؟
GraphQL هي لغة استعلام API مصممة لتوفير بديل أكثر كفاءة وقوة ومرونة لـ REST. يعتمد على أخذ عينات البيانات التصريحية ، أي أنه يمكن للعميل تحديد البيانات التي يحتاجها بالضبط من واجهة برمجة التطبيقات. بدلاً من نقاط النهاية المتعددة ، يمثل GraphQL API (REST) نقطة نهاية واحدة توفر للعميل البيانات المطلوبة.
الاختلافات الرئيسية بين REST و GraphQL
عادة في واجهة برمجة تطبيقات REST ، تحتاج إلى الحصول على معلومات من نقاط النهاية المختلفة. في GraphQL ، للحصول على نفس البيانات ، تحتاج إلى إجراء استعلام واحد يشير إلى البيانات التي تريد تلقيها.

يوفر REST API المعلومات التي سيضعها المطور في واجهة برمجة التطبيقات ، أي إذا كنت بحاجة إلى الحصول على معلومات أكثر أو أقل مما يقترح API ، فستكون هناك حاجة إلى إجراءات إضافية. مرة أخرى ، توفر GraphQL المعلومات المطلوبة بالضبط.
إضافة مفيدة هي أن GraphQL لديها مخطط يصف كيف وما هي البيانات التي يمكن للعميل استلامها.
أنواع الاستعلامات
يوجد 3 أنواع رئيسية من الاستعلامات في GraphQL:
سؤاليتم استخدام استعلامات الاستعلام لاسترداد / قراءة البيانات في مخطط.
مثال على هذا الطلب:
query { allPersons { name } }
في الطلب ، نشير إلى أننا نريد الحصول على أسماء جميع المستخدمين. بالإضافة إلى الاسم ، يمكننا تحديد الحقول الأخرى:
العمر ،
المعرف ،
المنشورات ، وما إلى ذلك. لمعرفة الحقول التي يمكننا الحصول عليها ، تحتاج إلى الضغط على Ctrl + Space. في هذا المثال ، نقوم بتمرير المعلمة التي سيعود بها التطبيق أول سجلين:
query { allPersons(first: 2) { name } }
تحولإذا كانت هناك حاجة إلى نوع الاستعلام لقراءة البيانات ، فسيكون نوع التحويل مطلوبًا لكتابة البيانات وحذفها وتعديلها في GraphQL.
مثال على هذا الطلب:
mutation { createPerson(name:"Bob", age: 37) { id name age } }
في هذا الطلب ، ننشئ مستخدمًا باسم Bob وعمره 37 (يتم تمرير هذه المعلمات كوسائط) ، في المرفق (الأقواس المعقوفة) نوضح البيانات التي نريد استلامها من الخادم بعد إنشاء المستخدم. يعد ذلك ضروريًا لفهم نجاح الطلب ، وكذلك للحصول على البيانات التي ينشئها الخادم بشكل مستقل ، مثل
id .
اشتراكنوع آخر من الاستعلام في GraphQL هو الاشتراك. هناك حاجة لإعلام المستخدمين بأي تغييرات حدثت في النظام. يعمل مثل هذا: يشترك العميل في بعض الأحداث ، وبعد ذلك يتم إنشاء اتصال مع الخادم (عادةً عبر WebSocket) ، وعندما يحدث هذا الحدث ، يرسل الخادم إشعارًا إلى العميل حول الاتصال الذي تم إنشاؤه.
مثال:
subscription { newPerson { name age id } }
عند إنشاء شخص جديد ، سيرسل الخادم معلومات إلى العميل. يعد وجود استعلامات الاشتراك في المخططات أقل شيوعًا من الاستعلام والطفرة.
تجدر الإشارة إلى أن جميع إمكانيات الاستعلام والطفرة والاشتراك يتم إنشاؤها وتكوينها من قبل مطور واجهة برمجة تطبيقات معينة.
اختياري
في الممارسة العملية ، غالبًا ما يستخدم المطورون الاسم المستعار و OperationName في الاستعلامات من أجل الوضوح.
الاسم المستعاريوفر GraphQL للاستعلامات ميزة الاسم المستعار ، والتي يمكن أن تجعل من السهل فهم ما يطلبه العميل.
لنفترض أن لدينا استفسار عن النموذج:
{ Person(id: 123) { age } }
الذي سيعرض اسم المستخدم
بمعرف 123. اسمح لهذا الاسم أن يكون Vasya.
بحيث في المرة القادمة التي لن تخيب فيها ما سيعرضه هذا الطلب ، يمكنك القيام بذلك بالشكل التالي:
{ Vasya: Person(id: 123) { age } }
OperationNameبالإضافة إلى الاسم المستعار ، يستخدم GraphQL اسم العملية:
query gettingAllPersons { allPersons { name age } }
اسم العملية مطلوب لتوضيح ما يفعله الطلب بالضبط.
Pentest
بعد أن اكتشفنا الأساسيات ، نذهب مباشرة إلى المكبوتة. كيف نفهم أن التطبيق يستخدم GraphQL؟ فيما يلي مثال استعلام يحتوي على استعلام GraphQL:
POST /simple/v1/cjp70ml3o9tpa0184rtqs8tmu/ HTTP/1.1 Host: api.graph.cool User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:65.0) Gecko/20100101 Firefox/65.0 Accept: */* Accept-Language: ru-RU,ru;q=0.8,en-US;q=0.5,en;q=0.3 Accept-Encoding: gzip, deflate Referer: https://api.graph.cool/simple/v1/cjp70ml3o9tpa0184rtqs8tmu/ content-type: application/json Origin: https://api.graph.cool Content-Length: 139 Connection: close {"operationName":null,"variables":{},"query":"{\n __schema {\n mutationType {\n fields {\n name\n }\n }\n }\n}\n"}
بعض المعلمات التي يمكنك من خلالها فهم أن هذا هو GraphQL ، وليس شيئًا آخر:
- توجد في نص الطلب كلمات: __schema ، حقول ، اسم عملية ، طفرة ، إلخ ؛
- يوجد في نص الطلب العديد من الأحرف "\ n". كما تبين الممارسة ، يمكن إزالتها لجعلها أكثر ملاءمة لقراءة الطلب ؛
- في كثير من الأحيان وسيلة لإرسال طلب إلى الخادم: ⁄graphql
عظيم ، وجدت وتحديدها. ولكن من
أين تُدرج علامة الاقتباس كيف تعرف ما الذي نحتاج إلى العمل معه؟ سوف التأمل يأتي إلى الإنقاذ.
استبطان
يوفر GraphQL نظامًا للتأمل الداخلي ، أي مخطط يصف البيانات التي يمكننا الحصول عليها. بفضل هذا ، يمكننا معرفة الطلبات الموجودة ، وما هي الحجج التي يمكن / ينبغي نقلها إليهم ، وأكثر من ذلك بكثير. لاحظ أنه في بعض الحالات ، لا يسمح المطورون عن عمد بإمكانية التأمل في تطبيقهم. ومع ذلك ، فإن الغالبية العظمى لا تزال تترك هذا الاحتمال.
النظر في الأمثلة الأساسية للاستعلامات.
مثال 1. الحصول على جميع أنواع الطلبات query { __schema { types { name fields { name } } } }
نقوم بتكوين استعلام استعلام ، ونشير إلى أننا نريد استلام البيانات على __schema ، وأنواعها وأسمائها وحقولها. في GraphQL ، توجد أسماء لمتغيرات الخدمة: __schema و __typename و __type.
في الإجابة ، سوف نتلقى جميع أنواع الطلبات وأسمائها وحقولها الموجودة في المخطط.
مثال 2. الحصول على حقول لنوع معين من الطلب (الاستعلام ، الطفرة ، الوصف) query { __schema { queryType { fields { name args { name } } } } }
ستكون الإجابة على هذا الطلب هي جميع الطلبات الممكنة التي يمكننا تنفيذها على مخطط استلام البيانات (نوع الاستعلام) ، والحجج الممكنة / الضرورية لها. بالنسبة إلى بعض الاستعلامات ، يلزم تحديد الوسيطة (الوسائط). إذا قمت بتنفيذ مثل هذا الطلب دون تحديد وسيطة مطلوبة ، يجب أن يعرض الخادم رسالة خطأ يجب عليك تحديدها. بدلاً من queryType ، يمكننا استبدال mutationType و subscriptionType للحصول على جميع الطلبات الممكنة للطفرات والاشتراكات ، على التوالي.
مثال 3. الحصول على معلومات حول نوع معين من الطلب query { __type(name: "Person") { fields { name } } }
بفضل هذا الاستعلام ، نحصل على جميع الحقول لنوع الشخص. كحجة ، بدلاً من الشخص ، يمكننا تمرير أي أسماء طلبات أخرى.
الآن وبعد أن استطعنا تحديد الهيكل العام للتطبيق قيد الاختبار ، دعونا نحدد ما نبحث عنه.
الكشف عن المعلوماتفي أغلب الأحيان ، يتألف التطبيق الذي يستخدم GraphQL من العديد من الحقول وأنواع الاستعلامات ، وكما يعلم الكثير من الناس ، كلما زاد تعقيد التطبيق وأكبر حجمًا ، كلما كان من الصعب تكوين الأمان ومراقبته. هذا هو السبب في وجود تأمل دقيق يمكنك أن تجد شيئًا مثيرًا للاهتمام ، على سبيل المثال: الأسماء الكاملة للمستخدمين وأرقام هواتفهم والبيانات الهامة الأخرى. لذلك ، إذا كنت ترغب في العثور على شيء مثل هذا ، فإننا نوصيك بالتحقق من جميع الحقول والوسيطات الممكنة للتطبيق. لذلك ، كجزء من البحث في أحد التطبيقات ، تم العثور على بيانات المستخدم: الاسم ، ورقم الهاتف ، وتاريخ الميلاد ، وبعض بيانات البطاقة ، إلخ.
مثال:
query { User(id: 1) { name birth phone email password } }
من خلال الاطلاع على قيم الهوية ، يمكننا الحصول على معلومات حول المستخدمين الآخرين (وربما لا ، إذا تم تكوين كل شيء بشكل صحيح).
الحقنوغني عن القول ، في كل مكان تقريبا حيث يوجد عمل مع كمية كبيرة من البيانات ، وهناك قواعد البيانات؟ وحيث توجد قاعدة بيانات - قد يكون هناك حقن SQL ، وحقن NoSQL وأنواع أخرى من الحقن.
مثال:
mutation { createPerson(name:"Vasya'--+") { name } }
إليك حقنة SQL أولية في وسيطة الاستعلام.
تجاوز الترخيصدعنا نقول أنه يمكننا إنشاء مستخدمين:
mutation { createPerson(username:"Vasya", password: "Qwerty1") { } }
على افتراض أن هناك معلمة معينة isAdmin في المعالج على الخادم ، يمكننا إرسال طلب من النموذج:
mutation { createPerson(username:"Vasya", password: "Qwerty1", isAdmin: True) { } }
وجعل المستخدم Vasya مسؤول.
دوس
بالإضافة إلى الراحة المعلنة ، لدى GraphQL ثغرات أمنية خاصة بها.
النظر في مثال:
query { Person { posts { author { posts { author { posts { author ... } } } } } } }
كما ترون ، أنشأنا استعلام فرعي حلقي. مع وجود عدد كبير من هذه الاستثمارات ، على سبيل المثال ، 50 ألفًا ، يمكننا إرسال طلب تتم معالجته بواسطة الخادم لفترة طويلة جدًا أو "إسقاطه" تمامًا. بدلاً من معالجة الطلبات الصحيحة ، سيكون الخادم مشغولا في تفريغ التداخل العملاق للطلب الوهمي.
بالإضافة إلى تداخل كبير ، يمكن أن تكون الاستعلامات نفسها "ثقيلة" - وهذا عندما يكون الاستعلام يحتوي على الكثير من الحقول والمرفقات الداخلية. يمكن أن يسبب هذا الطلب أيضًا صعوبات في المعالجة على الخادم.
استنتاج
لذلك ، درسنا المبادئ الأساسية لاختبار تغلغل التطبيقات مع GraphQL. نأمل أن تكون قد تعلمت شيئًا جديدًا ومفيدًا لك. إذا كنت مهتمًا بهذا الموضوع ، وترغب في دراسته بمزيد من التعمق ، فإننا نوصي بالموارد التالية:
ولا تنسى: الممارسة تجعلها مثالية. حظا سعيدا