
چند سال اخیر هر جا API مدرن میبینیم، احتمال اینکه پشتش GraphQL باشد کم نیست. خیلی از شرکتها به خاطر انعطاف بیشتر و کاهش تعداد درخواستها سراغ GraphQL رفتند. اما از دید یک تستر امنیت، GraphQL فقط یک API جدید نیست؛ یک سطح حمله جدید هم محسوب میشود.
در این مقاله میخواهیم ببینیم GraphQL چیست، چطور میشود آن را شناسایی کرد و مهمتر از همه، هنگام تست نفوذ چه چیزهایی را باید بررسی کنیم.
اگر قبلاً با REST کار کرده باشید، میدانید که معمولاً برای هر بخش از برنامه یک Endpoint جدا وجود دارد:
/api/users /api/posts /api/comments
اما در GraphQL معمولاً فقط یک Endpoint داریم:
/graphql
در GraphQL کلاینت مشخص میکند دقیقاً چه دادهای میخواهد و سرور هم فقط همان داده را برمیگرداند.
برای مثال فرض کنید میخواهیم اطلاعات یک کاربر و پستهایش را دریافت کنیم. در REST ممکن است مجبور باشیم چند درخواست جداگانه ارسال کنیم، اما در GraphQL همه چیز را میتوان در یک Query دریافت کرد.
همین انعطافپذیری باعث شده GraphQL محبوب شود، اما از طرفی کار تست نفوذ را هم کمی متفاوت کرده است.
در GraphQL همه چیز حول Objectها میچرخد.
مثلاً در یک سیستم وبلاگ میتوانیم این Objectها را داشته باشیم:
User
Post
Comment
هر Object تعدادی Field دارد.
برای مثال User میتواند شامل باشد:
username
role
همچنین Objectها میتوانند با هم ارتباط داشته باشند. مثلاً یک User چند Post داشته باشد و هر Post چند Comment.
به عنوان یک تستر امنیت، دقیقاً همین ارتباطها هستند که باید روی آنها حساس باشید؛ چون خیلی از مشکلات دسترسی از همین جا شروع میشوند.
در GraphQL سه نوع عملیات اصلی وجود دارد.
برای خواندن اطلاعات استفاده میشود.
برای ایجاد، حذف یا ویرایش دادهها استفاده میشود.
برای دریافت رویدادهای لحظهای استفاده میشود.
مثلاً زمانی که در یک سیستم چت پیام جدیدی دریافت میکنید یا در یوتیوب کانالی که دنبال میکنید ویدیوی جدید منتشر میکند.
اولین سؤال این است که اصلاً چطور بفهمیم یک برنامه از GraphQL استفاده میکند؟
معمولاً با مشاهده ترافیک برنامه در Burp Suite میتوان متوجه شد.
اگر درخواستها به Endpointهایی مثل موارد زیر ارسال شوند، احتمالاً با GraphQL طرف هستیم:
/graphql /graphiql /playground /graphql-playground
برای پیدا کردن Endpointها میتوان از روشهای مختلفی استفاده کرد:
Fuzzing
Google Dork
Wayback Machine
Nuclei
بررسی فایلهای JavaScript
ابزار Logger++ در Burp هم میتواند در شناسایی ترافیک GraphQL کمک زیادی کند.
یکی از چیزهایی که هنگام تست GraphQL همیشه دنبالش میگردم GraphiQL است.
GraphiQL یک رابط گرافیکی برای تست و دیباگ GraphQL است.
اگر این رابط در محیط Production در دسترس باشد، ممکن است بتوانیم:
Queryها را ببینیم
Mutationها را مشاهده کنیم
ساختار API را بررسی کنیم
مستندات API را بخوانیم
به همین دلیل دسترسی عمومی به GraphiQL در محیط عملیاتی معمولاً توصیه نمیشود.
بعد از پیدا کردن Endpoint، اولین چیزی که تست میکنم Introspection است.
Introspection قابلیتی است که به ما اجازه میدهد ساختار GraphQL را مشاهده کنیم.
اگر فعال باشد میتوانیم اطلاعاتی مثل:
Queryها
Mutationها
Typeها
Fieldها
ارتباط بین Objectها
را مشاهده کنیم.
به زبان ساده، Introspection مثل این است که نقشه کامل API را در اختیارمان قرار بدهند.
البته فعال بودن Introspection بهتنهایی آسیبپذیری محسوب نمیشود، اما میتواند فرآیند شناسایی را برای مهاجم بسیار سادهتر کند.
برای استخراج Schema ابزارهایی مثل InQL بسیار کاربردی هستند.
معمولاً روندی که برای تست GraphQL دنبال میکنم به این شکل است:
پیدا کردن Endpoint
بررسی GraphiQL یا Playground
تست Introspection
استخراج Schema
شناسایی Queryها و Mutationها
بررسی دسترسیها
تست Injection
بررسی SSRF
تست DoS
بررسی Rate Limiting
یکی از رایجترین مشکلات GraphQL مربوط به کنترل دسترسی است.
گاهی توسعهدهنده دسترسی به یک Query حساس را محدود کرده، اما همان اطلاعات از طریق یک Query دیگر یا از طریق ارتباط بین Objectها قابل دسترسی است.
برای همین هنگام تست GraphQL نباید فقط روی Queryهای اصلی تمرکز کرد. گاهی مسیرهای فرعی و Nested Queryها به اطلاعات حساس دسترسی میدهند.
GraphQL قرار نیست شما را در برابر SQL Injection یا NoSQL Injection محافظت کند.
در بسیاری از برنامهها ورودی کاربر از طریق Variables به Backend منتقل میشود و اگر اعتبارسنجی مناسب انجام نشده باشد، امکان وقوع Injection وجود دارد.
به همین دلیل بخش Variables یکی از مهمترین قسمتهایی است که باید بررسی شود.
هر جا دیدید یک Query یا Mutation آدرس URL دریافت میکند، احتمال SSRF را در نظر بگیرید.
برای مثال:
Import از URL
دریافت تصویر از URL
Webhook
URL Preview
این قابلیتها میتوانند باعث شوند سرور به درخواستهای دلخواه مهاجم پاسخ دهد.
بعضی Queryها پردازش سنگینی روی سرور انجام میدهند.
برای مثال:
تولید گزارش
پردازش فایل
تحلیل داده
جستجوهای پیچیده
اگر محدودیت مناسبی وجود نداشته باشد، میتوان از این قابلیتها برای مصرف منابع سرور سوءاستفاده کرد.
برخی پیادهسازیهای GraphQL اجازه میدهند چند Query در یک درخواست ارسال شود.
اگر محدودیتی روی تعداد عملیات وجود نداشته باشد، مهاجم میتواند حجم زیادی از درخواستها را در یک Request اجرا کند و فشار قابل توجهی روی سرور وارد کند.
یکی از معروفترین حملات GraphQL مربوط به Queryهای بازگشتی است.
در GraphQL ممکن است چند Object به هم وابسته باشند.
مهاجم میتواند با ایجاد Queryهای عمیق و تودرتو، سرور را مجبور به پردازش حجم زیادی از دادهها کند.
به همین دلیل بسیاری از Frameworkها مکانیزمهایی مثل:
Maximum Query Depth
Query Complexity Analysis
DEPTH_MAX
را پیادهسازی میکنند.
چند ابزار که هنگام تست GraphQL زیاد از آنها استفاده میشود:
Burp Suite
Logger++
InQL
GraphQLmap
Nuclei
Wayback Machine
GraphQL امکانات بسیار خوبی برای توسعهدهندگان فراهم میکند، اما در عین حال سطح حمله متفاوتی نسبت به REST ایجاد میکند.
اگر قصد تست نفوذ GraphQL را دارید، یادگیری مفاهیمی مثل Introspection، Schema Discovery، Authorization، Injection، SSRF و Query Complexity اهمیت زیادی دارد.
هرچه شناخت بهتری از ساختار GraphQL داشته باشید، احتمال پیدا کردن باگهای ارزشمند نیز بیشتر خواهد شد.