سیاست مبدأ مشترک، Same Origin Policy یا به اختصار SOP، مکانیزمی امنیتی در مرورگررهای وب است که هدف آن جلوگیری از حملهکردن وبسایتها به یکدیگر است.
سیاست SOP اجازه نمیدهد اسکریپتهای یک مبدأ (Origin)، به دادههای یک مبدأ دیگر دسترسی داشته باشند. مبدأ یا Origin تشکیل شده از اسکیم URI، دامنه و شماره پورت. برای مثال، URL زیر را در نظر بگیرید:
http://normal-website.com/example/example.html
این URL از اسکیم http استفاده میکند، دامنه آن normal-website.com است و شماره پورت آن نیز 80 است. جدول زیر نشان میدهد که اگر محتوا، یا به طور دقیقتر اسکریپتهای URL بالا سعی کنند به مبدأهای دیگری دسترسی پیدا کنند، سیاست مبدأ مشترک (SOP) چگونه اعمال میشود:
اجازه دسترسی داده میشود؟ | URL هدف دسترسی |
بله: اسکیم، دامنه و پورت یکسان | http://normal-website.com/example/ |
بله: اسکیم، دامنه و پورت یکسان | http://normal-website.com/example2/ |
نه: اسکیم و پورت متفاوت (پروتکل https از پورت متفاوتی نسبت به http استفاده میکند) | https://normal-website.com/example/ |
نه: دامنه متفاوت | http://en.normal-website.com/example/ |
نه: دامنه متفاوت | http://www.normal-website.com/example/ |
نه: پورت متفاوت* | http://normal-website.com:8080/example/ |
*اینترنت اکسپلورر اجازه این دسترسی را میدهد زیرا IE هنگام اعمال SOP به شماره پورت توجه نمیکند.
چرا به SOP نیاز داریم؟
وقتی یک مرورگر از یک مبدأ به مبدأ دیگر ریکوئست HTTP ارسال میکند، تمامی کوکیها، از جمله کوکیهای احراز هویت سشن مربوط به دامنهی مقصد را نیز همراه آن ارسال میکند. این یعنی پاسخ نیز در سشن کاربر تولید میشود، و حاوی تمام دادههای مرتبطی میشود که مخصوص آن کاربر هستند. برای مثال فرض کنید شما در سایت بانک خود لاگین کردهاید و اینگونه آن وبسایت یک سشن برای شما ایجاد کرده است؛ حالا مرورگر شما هر درخواست HTTP که به دامنه بانک شما ارسال کند، همراه آن کوکیهای احراز هویت را هم ارسال میکند تا سایت بانک متوجه شود که این ریکوئستها باید در محدوده سشن شما پردازش شوند و پاسخ آنها نیز در چارچوب سشن شما تولید شود. حال اگر یک وبسایت مخرب باز کنید و آن وبسایت از طریق مرورگر شما بخواهد به دامنه سایت ریکوئست بفرستد، به خاطر این که کوکیهای احراز هویت همراه آن ریکوئست ارسال میشوند، سایت بانک آن ریکوئست را در چارچوب سشن شما پردازش میکند.
یعنی هر کاری که در سایت بانک خود بکنید، سایت مخربی که باز کردهاید هم میتواند انجام دهد.
سیاست SOP اجازه نمیدهد یک مبدأ (وبسایت) به مبدأ دیگری از طریق مرورگر ریکوئست بفرستد تا از چنین مشکلی به وجود نیاید. اگر Same Origin Policy در مرورگرها وجود نداشت، زمانی که یک وبسایت مخرب را باز میکردید آن وبسایت میتوانست ایمیلهای شما را از صندوق ورودی جیمیل بخواند، به پیامهای خصوصی فیسبوک شما دسترسی داشته باشد و به طور خلاصه از همه مجوزهای سشنهای شما استفاده کند.
سیاست SOP چگونه پیادهسازی میشود؟
پالیسی SOP عموما دسترسیهایی را کنترل میکند که کد جاوااسکریپت به دادههای لودشده از دامنههای دیگر دارد. البته معمولا اجازه لودشدن منابع روی یک صفحه از مبدأهای دیگر داده میشود. مثلا SOP اجازهی لودشدن تصاویر با تگ <img> ویدئو با تگ <video> و کدهای جاوااسکریپت با تگ <script> را میدهد. با این حال علیرغم این که صفحه اجازه لودکردن این منابع خارجی را دارد، هیچ محتوای جاوااسکریپتی روی صفحه اجازهی خواندن محتویات این منابع را ندارد.
البته SOP استثناهایی هم دارد (در مثالها از آبجکتهای مختلف و پراپرتیهای آنها در جاوااسکریپت استفاده شده):
- بعضی محتواها به صورت فراوبگاهی یا cross-site قابل نوشتن هستند ولی قابل خواندن نیستند. مثل آبجکت location یا پراپرتی href در iframeها یا پنجرههای جدید.
- بعضی محتواها به صورت فراوبگاهی قابل خواندن هستند ولی قابل خواندن نیستند. مثل پراپرتی length از آبجکت window (که تعداد فریمهای استفاده شده روی صفحه را در خود نگه میدارد) و پراپرتی closed از آبجکت window.
- تابع replace را معمولا میتوان به صورت فراوبگاهی روی آبجکت location اجرا کرد.
- توابع خاصی به صورت فراوبگاهی قابل فراخوانی هستند. برای مثال، میتوانید توابع close، blur و focus را روی یک پنجره جدید اجرا کنید. تابع postMessage را نیز میتوان روی iframeها و پنجرههای جدید برای ارسال پیام از یک دامنه به دامنه دیگر.
به خاطر الزاماتی که از گذشته بیتغییر باقی ماندهاند، سیاست SOP برای کوکیها با سختگیری کمتری اعمال میشود و به همین خاطر کوکیها عمدتا از تمام سابدامینهای یک وبسایت هم قابل دسترسی هستند، در صورتی که هر سابدامین از لحاظ فنی یک مبدأ متفاوت محسوب میشود. با قراردادن فلگ HttpOnly در کوکی، میتوانید تا حدی این خطر را کمتر کنید.
با استفاده از پراپرتی document.domain میتوان پالیسی same origin را غیرفعال کرد. این پراپرتی خاص شما را قادر میکند SOP را برای یک دامنه خاص از کار بیندازید، البته فقط در صورتی که آن دامنه بخشی از FQDN (نامدامنه کاملا تاییدشده) شما باشد. برای مثال، ممکن است یک دامنه با نام marketing.example.com داشته باشید و بخواهید محتویات آن دامنه را روی example.com بخوانید. برای این کار، هر دو دامنه باید مقدار example.com را برای پراپرتی document.domain قرار داده باشند. در این صورت با وجود این که این دو دامنه مبدأهای متفاوتی محسوب میشوند، SOP اجازه دسترسی محتوا بین آنها را میدهد. در گذشته میشد مقدار پراپرتی document.domain را روی یک دامنه سطح بالا (TLD) مانند com تنظیم کرد؛ این کار باعث میشد دسترسی برای تمام دامنههای روی TLD یکسان مجاز شود، ولی مرورگرهای امروزی این اجازه را نمیدهند.