منظور از CORS چیست؟ درخواستهای Cross-Origin چه خصوصیاتی دارد؟ مفهوم Origin Policy به چه چیزی اطلاق میشود؟ CORS چه کاربردهایی دارد؟ منظور از Same-Origin Policy چیست؟ هر کدام از Headerهای CORS چه کاربردی دارند؟ در این مقاله به دنبال آشنایی با مفاهیم پیرامون CORS و کاربرد Headerهای آنها هستیم.
در سال 1995 مفهوم و concept ای معرفی شد که به دنبال ایجاد سازوکاری اتوماتیک و امنیتی برای مدیریت دسترسی و همچنین جلوگیری از دسترسی مدیریت نشدهی اسکریپتهای یک سرور به دیگر سرورها یا منابع سایر سرورها بود. این concept امروزه تحت عنوان origin policy شناخته میشود. هدف از origin policy ایجاد یک trust relationship بین کاربر و منابع تحت وب هست.
اما در دنیای وب در بسیاری از مواقع درخواستهایی که تحت صفحات وب ارسال میشود ممکن است برای لود منابع سرور یا origin ثانویه و دیگری باشد. یعنی در حقیقت کاربر دارد از origin دیگری منابع و دیتا را دریافت میکند. به این ترتیب که یک درخواستی روی یکorigin ، در اصل دارد منابع origin دیگری را طلب میکند. به این نوع درخواستها cross-origin گفته میشود. مثلن یک صفحهی وب مانند https://example.com/we.html خود در حال لود منابع از آدرس https://kingtest.com است. حتا درخواستها به یک Host واحد تحت پروتکلهای مختلف هم cross-origin محسوب میشود. یعنی مثلن http://kingtest.com/null.html خود در حال زدن درخواست به https://kingtest.com/main.html است. در نظر داشته باشید که منظور از origin همان هاست نیست، بلکه origin عبارت است از ترکیب پروتکل، هاست و path . پس اگر هر کدام از این سه تغییر کند، درخواست میشود از نوع cross-origin . (یعنی به origin دیگر)
اما cors policy خود در دو بخش Same-Origin و Cross-Origin به نوعی تفکیک شده است که در ادامه به صورت مجزا به بررسی این دو میپردازیم.
معرفی Same-Origin Policy یا SOP
یکی از سازوکارهای امنیتی که امروزه در هر مرورگر وجود دارد same-origin policy هست. این قابلیت در مرورگر باعث کنترل ارتباط اسکریپتهای در حال اجرا با منابع دیگر روی همان origin میشود و محدودیتهایی برای جلوگیری از سواستفاده از منابع وبسرور در مرورگر اعمال میکند. در واقع SOP در مرورگر جلوی دسترسی مدیریت نشدهی مثلن Javascript (و سایر زبانهای اسکریپت نویسی وب) را به web document ها میگیرد و تغییراتی که از سمت programming interface ها تحت وب روی داکیومنتها اعمال میشود را کنترل میکند. این امر جلوی سواستفادهی هکرها و اسکریپتهای مخرب در وب را تا حدودی میگیرد. SOP برای ایجاد trust relationship از URI ها استفاده میکند. اما SOP مدیریت چندانی روی ارتباط بین origin های مختلف ندارد. از این رو برای اعمال کامل origin policy روی ارتباط بین سرورهای متفاوت به سازوکار مکمل دیگری نیز احتیاج داریم که CORS نامیده میشود.
اما SOP در کنار تمام مزیتهایی که داشت، کمی سختگیرانه بود و زیادی جلوی ارتباط (کدهای مثلن Javascript ) با منابع سایر origin ها را میگرفت در حالی که کاربران امروزی موقع کار با وب نیاز به دسترسی به منابع سایر origin ها را نیز دارند و نمیتوان این نیاز را نادیده گرفت. از این رو CORS باعث میشود برخی محدودیتهای SOP تحت شرایطی bypass شود زیرا CORS به دنبال ساده کردن مدیریت resource sharing بین سرورها تحت وب هست. همانطور که میدانید بنا به دلایل امنیتی مرورگرها روی درخواستهایی که تحت HTTP به صورت cross-origin ارسال میشوند، محدودیتهایی قرار میدهند. یعنی اگر شما بخواهید از یک اپلیکیشن frontend ای به API ای (که در origin دیگری قرار دارد) دسترسی پیدا کنید، به صورت پیشفرض مرورگر و سرور مقصد اجازهی انجام این درخواست را نمیدهند.
در واقع CORS به مرورگرها و وبسرور ها امکان نوعی سنجش میدهد، سنجش و بررسی اینکه آیا در فرآیند resource sharing ممکن است تهدیدی وجود داشته باشد یا خیر. از این رو CORS با هدف سیاستگذاری و کنترل ریکوستهای cross-origin ایجاد شده است. به عبارت دیگر CORS باعث ایجاد سازوکاری برای کنترل دسترسی به منابع origin های دیگر است. با CORS میتوان مجموعهای از rule ها را تعریف کرد و مشخص کرد که چه نوع درخواستهایی توسط وبسرور پاسخ داده شود، همچنین مشخص کرد که از کجاها و با چه متدی به منابع دسترسی وجود داشته باشد. به صورت پیشفرض rule ای ست نشده است و دسترسیها بسته هست و SOP با تاثیر غیرمستقیماش اجازهی این ارتباط را نمیدهد. اما CORS برای تعریف این rule ها و تعیین شرایط دسترسی از تعدادی Header استفاده میکند که در ادامه به معرفی چند مورد از مطرحترین آنها خواهیم پرداخت.
هدر Access-Control-Allow-Origin
این Header مشخص میکند که کدام origin میتواند به منابع وبسرور دسترسی داشته باشد. این هدر سمت مقصد ست میشود و توسط مقصد برای مرورگر ارسال میشود و به مرورگر میگوید که چه origin ای اجازهی دسترسی به منابعاش را دارد. مثلن وبسرور A تعیین میکند که تنها origin با مشخصات https://kingtest.ir به منابعاش دسترسی داشته باشد. اگر وبسرور A بخواهد کلن محدودیت را برای همه بردارد، میتواند مقدار این Header را مثلن برابر * قرار دهد تا تمام origin ها به منابعاش دسترسی پیدا کنند.
هدر Access-Control-Allow-Methods
در این Header مقصد(وب سرور A ) به مرورگر اعلام میکند که چه HTTP method هایی را در درخواستها میپذیرد. مثلن POST ، GET یا ...
هدر Access-Control-Allow-Headers
توسط این Header، سایر Headerهای ارسالی که وب سرور میپذیرد تعیین میشود.
معرفی Preflight request ها در CORS
اما زمانی که قرار هست در ارتباط با وبسرور یکسری Headerها چک شوند، نیاز هست که خود این اطلاعات از وبسرورها درخواست شوند تا اگر خطایی رخ داد و یا دسترسی origin ای باز نبود، بفهمیم روی کدام rule شرایط رعایت نشده و به عبارت بهتر وبسرور چه شرایطی را روی Headerهای CORS تعریف کرده است. این امر به کمک Preflight request صورت میگیرد.
مکانیسم CORS برای فرآیند request permission از قابلیت Preflight request استفاده میکند. در واقع Preflight request ها پیشدرخواستهایی هستند که توسط مرورگرها به سمت سرورها ارسال میشود، برای چک کردن اینکه آیا اصلن rule ای ست شده است؟ یا خیر. یا اینکه سرور به چه Headerها و متدهایی اجازهی ارتباط میدهد.
به عنوان نتیجهگیری و به طور خلاصه؛ CORS یک مکانیسم header-based است که rule ها و قوانینی را برای استفاده از منابع وبسرور تعیین میکند. شایان ذکر است که CORS به معنای تامین امنیت نیست و وجود SOP و پیاده سازی CORS امنیت کامل سایت را تامین نمیکند.