رمزگشایی امنیت GraphQL: راهنمای جامع برای درون نگری
این پست توسط آنتوان خواندن در وبلاگ ما راحت تر است
غیرفعال کردن یا عدم غیرفعال کردن درون نگری یکی از بحث های رایج در میان توسعه دهندگان GraphQL از زمان پیدایش آن بوده است. در این پست وبلاگ توضیح خواهیم داد که چرا غیرفعال کردن کامل درون نگری ضروری نیست و چرا می تواند نتیجه معکوس داشته باشد.
من واقعاً هیچ دلیل خوبی برای مسدود کردن/حذف کردن پیدا نمی کنم #GraphQL قابلیت های درون نگری به دلایل امنیتی به نظر بسیار شبیه “امنیت از طریق ابهام” است.
آیا کسی میتواند به چیزی فکر کند که بهتر نمیتوان آن را با فیلترهای دید و/یا فهرست سفید جستجو حل کرد؟
01:41 – 28 ژانویه 2020
مارک آندره ژیرو، نویسنده GraphQL آماده تولید
چرا درون نگری مفید است؟
درون نگری چیست؟
در مرحله اول، درک اینکه Introspection در GraphQL چیست، ضروری است. این توانایی ارائه ابرداده در مورد طرحواره خود، از جمله انواع، فیلدها و دستورالعمل ها است. این به توسعه دهندگان اجازه می دهد تا ساختار API را بررسی کنند و داده های موجود را درک کنند.
ساده ترین راه برای اینکه بفهمید آیا درون نگری شما باز است یا نه این است که خودتان آن را بیاورید!
curl --location 'https://example.com/graphql' \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '{"query":"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 } } } } } } } }","variables":{}}' \ > introspection.json
دستور curl introspection
یک ویژگی ضروری برای بهره وری و انعطاف پذیری
Introspection یک ویژگی مفید برای توسعه دهندگان فرانت اند و مشتری است. به طور خاص، یکی از مهم ترین مزایای GraphQL این است که به آنها اجازه می دهد فقط داده های مورد نیاز خود را درخواست کنند. درون نگری نقش مهمی در این فرآیند ایفا می کند و آنها را قادر می سازد تا انواع و زمینه های موجود در طرحواره را کشف و درک کنند.
با غیرفعال کردن درون نگری، در اصل یک ابزار ارزشمند را از بین می برید که توسعه دهندگان می توانند از آن برای بهبود بهره وری خود استفاده کنند و تصمیمات آگاهانه تری در مورد نحوه ساختار پرس و جوهای خود بگیرند.
علاوه بر این، Introspection می تواند ابزار ارزشمندی برای مستندسازی و کشف API باشد. با غیرفعال کردن آن در تولید، ممکن است لازم باشد منابع بیشتری را برای نگهداری اسناد جداگانه و به روز نگه داشتن آن سرمایه گذاری کنید. این می تواند پیچیدگی فرآیند نگهداری API شما را افزایش دهد و به طور بالقوه منجر به ناسازگاری بین طرح واقعی و مستندات شود.
آیا درون نگری واقعاً یک نگرانی امنیتی است؟
به نظر می رسد یک خطر امنیتی بالقوه است
استدلال اصلی برای غیرفعال کردن درون نگری این است که می تواند یک خطر امنیتی باشد. با اجازه دادن به درون نگری، عوامل مخرب می توانند از این اطلاعات برای ایجاد حملات هدفمند علیه برنامه شما سوء استفاده کنند. به ویژه، به طور بالقوه می تواند نقاط ورودی اضافی، مانند عملیات پنهان یا غیرمستند را که ممکن است به اندازه بقیه برنامه شما ایمن نباشند، در معرض دید قرار دهد.
همچنین می تواند یک مشکل عملکردی باشد. هنگامی که یک سرور GraphQL یک جستجوی درون نگری دریافت می کند، باید کل طرحواره را طی کند و ابرداده را جمع آوری کند، که می تواند زمان بر و منابع فشرده باشد.
جایی که اراده وجود دارد؛ راهی هست
در آن مرحله، ممکن است غیرفعال کردن درون نگری برای اهداف امنیتی بدیهی به نظر برسد. مشکل این است که غیرفعال کردن آن فقط یک “ایده خوب نادرست” است. همیشه یک راه ساده برای پیدا کردن طرحواره و ایجاد درخواست های مخرب در برابر GraphQL API شما وجود دارد.
پیشنهاد فیلد طرح شما را لو می دهد
اکثر موتورهای GraphQL دارای ویژگی به نام Field Suggestion هستند. هنگامی که سرور درخواستی با فیلدهای نامعتبر دریافت می کند، با یک پیغام خطا پاسخ می دهد که نشان می دهد فیلد درخواستی وجود ندارد.
با این حال، این پیام خطا همچنین حاوی اطلاعاتی در مورد فیلدهایی با نام های مشابه است که در طرحواره وجود دارند. این ویژگی GraphQL Field Suggestion نام دارد.
{
"errors": [
{
"message": "Cannot query field \"space\" on type \"Query\". Did you mean \"escape\"?",
"locations": [
{
"line": 1,
"column": 5
}
],
"extensions": {
"code": "GRAPHQL-VALIDATION-FAILED"
}
}
]
}
پیشنهاد فیلد در GraphQL
می توان از این ویژگی سوء استفاده کرد: با ارسال نام فیلدهای تصادفی در یک پرس و جو و جمع آوری پیشنهاداتی که سرورها ارسال می کنند، می توان طرح کامل GraphQL را بازسازی کرد! این حمله ای به نام Field Fuzzing است.
Clairvoyance یک ابزار منبع باز است که توسط Nikita Stupin ایجاد شده و توسط Escape نگهداری می شود که به توسعه دهندگان اجازه می دهد تا داده های درون نگری GraphQL را حتی در صورت غیرفعال شدن با استفاده از Field Fuzzing بازیابی کنند.
با تجزیه و تحلیل این پیام های خطا، Clairvoyance می تواند ساختار طرحواره را تعیین کند و داده های درون نگری لازم را بازیابی کند.
در سرورهای Apollo و Yoga، میتوانید Field Suggestion را با استفاده از ابزار رایگان و منبع باز GraphQL Armor غیرفعال کنید.
طرف مقابل همه چیز را می داند.
بدیهی است که می توان درون گرایی را از ترافیک ایجاد شده توسط یک front-end بازسازی کرد. این بدان معناست که حتی اگر درون نگری را غیرفعال کنید، یک مهاجم مصمم همچنان میتواند با پیمایش به وبسایت برنامه شما به اطلاعات طرح دسترسی پیدا کند.
درون نگری من فقط در صحنه سازی فعال است
آیا فکر میکنید باز نگه داشتن دروننگاری خود در صحنهسازی، تولید شما را ایمنتر میکند؟
بیشتر اوقات، ما متوجه می شویم که اگر نقطه پایان تولید شما در دسترس باشد https://graphql.example.com/
، محیط صحنه سازی شما از طریق قابل دسترسی است https://staging.graphql.example.com/
. در این صورت، دریافت درون نگری صحنهپردازیتان بیمعنی است.
فرض کنید سعی کرده اید محیط مرحله بندی خود را روی یک URL تصادفی پنهان کنید. در Escape، ما نرم افزار منبع باز را برای یافتن هر نقطه پایانی GraphQL مرتبط با برنامه اصلی شما توسعه دادیم.
با استفاده از شمارش دامنههای فرعی، خزیدن وب و اجبار بیرحمانه، Goctopus میتواند هر یک از نقاط پایانی GraphQL شما را پیدا کند و بداند که آیا درونبینی یا پیشنهادات میدانی در هر یک از آنها فعال است یا خیر.
ما از Goctopus در پلتفرم خودمان، Escape، برای ایندکس کردن تمام نقاط پایانی GraphQL مشتریانمان استفاده میکنیم. ما متوجه شدیم که تعداد بسیار زیادی از سازمانها محیط مرحلهبندی و توسعه خود را با دروننگری فعال دارند.
نتیجه گیری: بهره وری را با ابهام مبادله نکنید
در Escape، ما به امنیت از طریق ابهام اعتقاد داریم، و بنابراین توصیه می کنیم که درون نگری را غیرفعال نکنید.
You can keep your introspection enabled: Completely disabling introspection doesn't actually make your server more secure; it just makes it harder for developers to do their jobs.
Optionally, implement role-based access control: If you still don't fill confident in letting your introspection open to the world, you can configure your GraphQL server to enable introspection only for specific user roles, such as administrator or developers, ensuring the feature is accessible only to trusted users. See more details in our documentation.
در نهایت، تصمیم گیری برای غیرفعال کردن درون نگری در تولید بستگی به مورد استفاده و الزامات خاص شما دارد. اطمینان حاصل کنید که با حفظ یک برنامه قوی، بهترین تجربه را به توسعه دهندگان خود ارائه می دهید.