بسیاری از برنامه های کاربردی وب نیاز به نمایش محتوای کنترل شده توسط کاربر دارند. این می تواند به سادگی ارائه تصاویر آپلود شده توسط کاربر (به عنوان مثال، عکس های نمایه)، یا به پیچیدگی ارائه HTML کنترل شده توسط کاربر (به عنوان مثال، آموزش توسعه وب) باشد. انجام این کار به صورت ایمن همیشه دشوار بوده است، بنابراین ما برای یافتن راهحلهای آسان، اما مطمئنی که میتوانند در اکثر انواع برنامههای کاربردی وب اعمال شوند، کار کردهایم.
راه حل های کلاسیک برای جداسازی محتوای غیرقابل اعتماد
راه حل کلاسیک برای ارائه ایمن محتوای کنترل شده توسط کاربر، استفاده از مواردی است که به عنوان دامنه های sandbox شناخته می شوند. ایده اصلی این است که اگر دامنه اصلی برنامه شما example.com
است، میتوانید تمام محتوای غیرقابل اعتماد را در exampleusercontent.com
ارائه دهید. از آنجایی که این دو دامنه متقابل سایت هستند، هرگونه محتوای مخرب در exampleusercontent.com
نمی تواند روی example.com
تأثیر بگذارد.
این رویکرد می تواند برای ارائه ایمن انواع محتوای غیرقابل اعتماد از جمله تصاویر، دانلودها و HTML استفاده شود. اگرچه ممکن است استفاده از آن برای تصاویر یا دانلودها ضروری به نظر نرسد، انجام این کار به جلوگیری از خطرات ناشی از استفراغ محتوا ، به خصوص در مرورگرهای قدیمی کمک می کند.
دامنه های Sandbox به طور گسترده در سراسر صنعت استفاده می شوند و برای مدت طولانی به خوبی کار می کنند. اما، آنها دو نقطه ضعف عمده دارند:
- برنامهها اغلب نیاز دارند دسترسی به محتوا را به یک کاربر محدود کنند، که نیاز به اجرای احراز هویت و مجوز دارد. از آنجایی که دامنه های sandbox به طور هدفمند کوکی ها را با دامنه برنامه اصلی به اشتراک نمی گذارند، انجام این کار به صورت ایمن بسیار دشوار است. برای پشتیبانی از احراز هویت، سایت ها یا باید به URL های قابلیت تکیه کنند یا باید کوکی های احراز هویت جداگانه را برای دامنه sandbox تنظیم کنند. این روش دوم به ویژه در وب مدرن که در آن بسیاری از مرورگرها کوکی های بین سایتی را به طور پیش فرض محدود می کنند مشکل ساز است.
- در حالی که محتوای کاربر از سایت اصلی جدا شده است، از سایر محتوای کاربر جدا نیست. این خطر حمله محتوای مخرب کاربر به سایر دادهها در دامنه sandbox را ایجاد میکند (به عنوان مثال، از طریق خواندن دادههای همان منبع).
همچنین شایان ذکر است که دامنه های sandbox به کاهش خطرات فیشینگ کمک می کنند زیرا منابع به وضوح در یک دامنه ایزوله تقسیم می شوند.
راه حل های مدرن برای ارائه محتوای کاربر
با گذشت زمان وب تکامل یافته است و اکنون راه های آسان تر و ایمن تری برای ارائه محتوای غیرقابل اعتماد وجود دارد. در اینجا رویکردهای مختلفی وجود دارد، بنابراین ما دو راه حل را که در حال حاضر به طور گسترده در گوگل مورد استفاده قرار می گیرند، بیان می کنیم.
رویکرد 1: ارائه محتوای غیرفعال کاربر
اگر یک سایت فقط نیاز به ارائه محتوای غیرفعال کاربر دارد (یعنی محتوایی که HTML یا جاوا اسکریپت نیست، برای مثال تصاویر و دانلودها)، اکنون میتوان این کار را با خیال راحت بدون دامنه سندباکس ایزوله انجام داد. دو مرحله کلیدی وجود دارد:
- همیشه هدر
Content-Type
را روی یک نوع MIME شناخته شده تنظیم کنید که توسط همه مرورگرها پشتیبانی میشود و تضمین میشود که حاوی محتوای فعال نباشد (در صورت شک،application/octet-stream
یک انتخاب مطمئن است). - علاوه بر این، همیشه سرفصلهای پاسخ زیر را تنظیم کنید تا مطمئن شوید که مرورگر پاسخ را کاملاً ایزوله میکند.
سربرگ پاسخ | هدف |
---|---|
X-Content-Type-Options: nosniff | از بو کشیدن محتوا جلوگیری می کند |
Content-Disposition: attachment; filename="download" | به جای ارائه، بارگیری را آغاز می کند |
Content-Security-Policy: sandbox | محتوا را طوری قرار می دهد که گویی در یک دامنه جداگانه ارائه شده است |
Content-Security-Policy: default-src ‘none' | غیرفعال کردن اجرای جاوا اسکریپت (و گنجاندن هر منبع فرعی) |
Cross-Origin-Resource-Policy: same-site | از قرار گرفتن صفحه بین سایتی جلوگیری می کند |
این ترکیب از هدرها تضمین می کند که پاسخ فقط می تواند به عنوان یک منبع فرعی توسط برنامه شما بارگیری شود یا به عنوان یک فایل توسط کاربر بارگیری شود. علاوه بر این، هدرها چندین لایه محافظت در برابر اشکالات مرورگر را از طریق هدر CSP sandbox و محدودیت default-src
فراهم میکنند. به طور کلی، تنظیمات ذکر شده در بالا درجه بالایی از اطمینان را فراهم می کند که پاسخ هایی که به این روش ارائه می شوند نمی توانند منجر به آسیب پذیری های تزریق یا جداسازی شوند.
دفاع در عمق
در حالی که راه حل فوق یک دفاع کلی در برابر XSS را نشان می دهد، تعدادی از اقدامات سخت کننده اضافی وجود دارد که می توانید برای ارائه لایه های امنیتی اضافی اعمال کنید:
- یک هدر
X-Content-Security-Policy: sandbox
برای سازگاری با IE11 تنظیم کنید. - یک
Content-Security-Policy: frame-ancestors 'none'
برای جلوگیری از تعبیه شدن نقطه پایانی. - محتوای کاربر Sandbox در یک زیر دامنه جدا شده توسط:
- ارائه محتوای کاربر در یک زیر دامنه مجزا (مثلاً Google از دامنههایی مانند
product.usercontent.google.com
استفاده میکند). -
Cross-Origin-Opener-Policy: same-origin
وCross-Origin-Embedder-Policy: require-corp
برای فعال کردن جداسازی مبدا متقاطع تنظیم کنید.
- ارائه محتوای کاربر در یک زیر دامنه مجزا (مثلاً Google از دامنههایی مانند
رویکرد 2: ارائه محتوای فعال کاربر
ارائه ایمن محتوای فعال (به عنوان مثال، تصاویر HTML یا SVG) همچنین می تواند بدون نقاط ضعف رویکرد دامنه sandbox کلاسیک انجام شود.
ساده ترین گزینه این است که از هدر Content-Security-Policy: sandbox
استفاده کنید تا به مرورگر بگویید پاسخ را ایزوله کند. در حالی که همه مرورگرهای وب در حال حاضر جداسازی فرآیند را برای اسناد جعبه ایمنی پیادهسازی نمیکنند، اصلاحات مداوم در مدلهای فرآیند مرورگر احتمالاً جداسازی محتوای جعبهشنی را از برنامههای کاربردی تعبیهشده بهبود میبخشد. اگر حملات SpectreJS و رندر ساز خارج از مدل تهدید شما هستند، استفاده از جعبه ایمنی CSP احتمالا راه حل کافی است.
در Google، راهحلی ایجاد کردهایم که میتواند محتوای فعال غیرقابل اعتماد را با مدرنسازی مفهوم دامنههای sandbox کاملاً ایزوله کند. ایده اصلی این است که:
- یک دامنه sandbox جدید ایجاد کنید که به لیست پسوند عمومی اضافه شود. به عنوان مثال، با افزودن
exampleusercontent.com
به PSL، می توانید اطمینان حاصل کنید کهfoo.exampleusercontent.com
وbar.exampleusercontent.com
متقابل سایت هستند و بنابراین کاملاً از یکدیگر جدا هستند. - URL های مطابق با
*.exampleusercontent.com/shim
همگی به یک فایل شیم ثابت هدایت می شوند. این فایل شیم حاوی یک قطعه کوتاه HTML و جاوا اسکریپت است که به کنترل کننده رویدادmessage
گوش می دهد و هر محتوایی را که دریافت می کند ارائه می کند. - برای استفاده از این، محصول یک iframe یا یک پنجره بازشو در
$RANDOM_VALUE.exampleusercontent.com/shim
ایجاد میکند و ازpostMessage
برای ارسال محتوای غیرقابل اعتماد به شیم برای رندر استفاده میکند. - محتوای رندر شده به یک Blob تبدیل میشود و در داخل یک iframe جعبهشنودی رندر میشود.
در مقایسه با رویکرد کلاسیک دامنه سندباکس، این تضمین میکند که تمام محتوا به طور کامل در یک سایت منحصر به فرد جدا شده است. و با داشتن برنامه اصلی با بازیابی داده هایی که باید ارائه شوند، دیگر نیازی به استفاده از URL های قابلیت نیست.
نتیجه گیری
این دو راهحل با هم، انتقال دامنههای sandbox کلاسیک مانند googleusercontent.com
را به راهحلهای امنتر که با مسدود کردن کوکیهای شخص ثالث سازگار هستند، ممکن میسازد. در Google، ما قبلاً بسیاری از محصولات را برای استفاده از این راهحلها منتقل کردهایم و برای سال آینده برنامهریزی بیشتری برای مهاجرت داریم.
بسیاری از برنامه های کاربردی وب نیاز به نمایش محتوای کنترل شده توسط کاربر دارند. این می تواند به سادگی ارائه تصاویر آپلود شده توسط کاربر (به عنوان مثال، عکس های نمایه)، یا به پیچیدگی ارائه HTML کنترل شده توسط کاربر (به عنوان مثال، آموزش توسعه وب) باشد. انجام این کار به صورت ایمن همیشه دشوار بوده است، بنابراین ما برای یافتن راهحلهای آسان، اما مطمئنی که میتوانند در اکثر انواع برنامههای کاربردی وب اعمال شوند، کار کردهایم.
راه حل های کلاسیک برای جداسازی محتوای غیرقابل اعتماد
راه حل کلاسیک برای ارائه ایمن محتوای کنترل شده توسط کاربر، استفاده از مواردی است که به عنوان دامنه های sandbox شناخته می شوند. ایده اصلی این است که اگر دامنه اصلی برنامه شما example.com
است، میتوانید تمام محتوای غیرقابل اعتماد را در exampleusercontent.com
ارائه دهید. از آنجایی که این دو دامنه متقابل سایت هستند، هرگونه محتوای مخرب در exampleusercontent.com
نمی تواند روی example.com
تأثیر بگذارد.
این رویکرد می تواند برای ارائه ایمن انواع محتوای غیرقابل اعتماد از جمله تصاویر، دانلودها و HTML استفاده شود. اگرچه ممکن است استفاده از آن برای تصاویر یا دانلودها ضروری به نظر نرسد، انجام این کار به جلوگیری از خطرات ناشی از استفراغ محتوا ، به خصوص در مرورگرهای قدیمی کمک می کند.
دامنه های Sandbox به طور گسترده در سراسر صنعت استفاده می شوند و برای مدت طولانی به خوبی کار می کنند. اما، آنها دو نقطه ضعف عمده دارند:
- برنامهها اغلب نیاز دارند دسترسی به محتوا را به یک کاربر محدود کنند، که نیاز به اجرای احراز هویت و مجوز دارد. از آنجایی که دامنه های sandbox به طور هدفمند کوکی ها را با دامنه برنامه اصلی به اشتراک نمی گذارند، انجام این کار به صورت ایمن بسیار دشوار است. برای پشتیبانی از احراز هویت، سایت ها یا باید به URL های قابلیت تکیه کنند یا باید کوکی های احراز هویت جداگانه را برای دامنه sandbox تنظیم کنند. این روش دوم به ویژه در وب مدرن که در آن بسیاری از مرورگرها کوکی های بین سایتی را به طور پیش فرض محدود می کنند مشکل ساز است.
- در حالی که محتوای کاربر از سایت اصلی جدا شده است، از سایر محتوای کاربر جدا نیست. این خطر حمله محتوای مخرب کاربر به سایر دادهها در دامنه sandbox را ایجاد میکند (به عنوان مثال، از طریق خواندن دادههای همان منبع).
همچنین شایان ذکر است که دامنه های sandbox به کاهش خطرات فیشینگ کمک می کنند زیرا منابع به وضوح در یک دامنه ایزوله تقسیم می شوند.
راه حل های مدرن برای ارائه محتوای کاربر
با گذشت زمان وب تکامل یافته است و اکنون راه های آسان تر و ایمن تری برای ارائه محتوای غیرقابل اعتماد وجود دارد. در اینجا رویکردهای مختلفی وجود دارد، بنابراین ما دو راه حل را که در حال حاضر به طور گسترده در گوگل مورد استفاده قرار می گیرند، بیان می کنیم.
رویکرد 1: ارائه محتوای غیرفعال کاربر
اگر یک سایت فقط نیاز به ارائه محتوای غیرفعال کاربر دارد (یعنی محتوایی که HTML یا جاوا اسکریپت نیست، برای مثال تصاویر و دانلودها)، اکنون میتوان این کار را با خیال راحت بدون دامنه سندباکس ایزوله انجام داد. دو مرحله کلیدی وجود دارد:
- همیشه هدر
Content-Type
را روی یک نوع MIME شناخته شده تنظیم کنید که توسط همه مرورگرها پشتیبانی میشود و تضمین میشود که حاوی محتوای فعال نباشد (در صورت شک،application/octet-stream
یک انتخاب مطمئن است). - علاوه بر این، همیشه سرفصلهای پاسخ زیر را تنظیم کنید تا مطمئن شوید که مرورگر پاسخ را کاملاً ایزوله میکند.
سربرگ پاسخ | هدف |
---|---|
X-Content-Type-Options: nosniff | از بو کشیدن محتوا جلوگیری می کند |
Content-Disposition: attachment; filename="download" | به جای ارائه، بارگیری را آغاز می کند |
Content-Security-Policy: sandbox | محتوا را طوری قرار می دهد که گویی در یک دامنه جداگانه ارائه شده است |
Content-Security-Policy: default-src ‘none' | غیرفعال کردن اجرای جاوا اسکریپت (و گنجاندن هر منبع فرعی) |
Cross-Origin-Resource-Policy: same-site | از قرار گرفتن صفحه بین سایتی جلوگیری می کند |
این ترکیب از هدرها تضمین می کند که پاسخ فقط می تواند به عنوان یک منبع فرعی توسط برنامه شما بارگیری شود یا به عنوان یک فایل توسط کاربر بارگیری شود. علاوه بر این، هدرها چندین لایه محافظت در برابر اشکالات مرورگر را از طریق هدر CSP sandbox و محدودیت default-src
فراهم میکنند. به طور کلی، تنظیمات ذکر شده در بالا درجه بالایی از اطمینان را فراهم می کند که پاسخ هایی که به این روش ارائه می شوند نمی توانند منجر به آسیب پذیری های تزریق یا جداسازی شوند.
دفاع در عمق
در حالی که راه حل فوق یک دفاع کلی در برابر XSS را نشان می دهد، تعدادی از اقدامات سخت کننده اضافی وجود دارد که می توانید برای ارائه لایه های امنیتی اضافی اعمال کنید:
- یک هدر
X-Content-Security-Policy: sandbox
برای سازگاری با IE11 تنظیم کنید. - یک
Content-Security-Policy: frame-ancestors 'none'
برای جلوگیری از تعبیه شدن نقطه پایانی. - محتوای کاربر Sandbox در یک زیر دامنه جدا شده توسط:
- ارائه محتوای کاربر در یک زیر دامنه مجزا (مثلاً Google از دامنههایی مانند
product.usercontent.google.com
استفاده میکند). -
Cross-Origin-Opener-Policy: same-origin
وCross-Origin-Embedder-Policy: require-corp
برای فعال کردن جداسازی مبدا متقاطع تنظیم کنید.
- ارائه محتوای کاربر در یک زیر دامنه مجزا (مثلاً Google از دامنههایی مانند
رویکرد 2: ارائه محتوای فعال کاربر
ارائه ایمن محتوای فعال (به عنوان مثال، تصاویر HTML یا SVG) همچنین می تواند بدون نقاط ضعف رویکرد دامنه sandbox کلاسیک انجام شود.
ساده ترین گزینه این است که از هدر Content-Security-Policy: sandbox
استفاده کنید تا به مرورگر بگویید پاسخ را ایزوله کند. در حالی که همه مرورگرهای وب در حال حاضر جداسازی فرآیند را برای اسناد جعبه ایمنی پیادهسازی نمیکنند، اصلاحات مداوم در مدلهای فرآیند مرورگر احتمالاً جداسازی محتوای جعبهشنی را از برنامههای کاربردی تعبیهشده بهبود میبخشد. اگر حملات SpectreJS و رندر ساز خارج از مدل تهدید شما هستند، استفاده از جعبه ایمنی CSP احتمالا راه حل کافی است.
در Google، راهحلی ایجاد کردهایم که میتواند محتوای فعال غیرقابل اعتماد را با مدرنسازی مفهوم دامنههای sandbox کاملاً ایزوله کند. ایده اصلی این است که:
- یک دامنه sandbox جدید ایجاد کنید که به لیست پسوند عمومی اضافه شود. به عنوان مثال، با افزودن
exampleusercontent.com
به PSL، می توانید اطمینان حاصل کنید کهfoo.exampleusercontent.com
وbar.exampleusercontent.com
متقابل سایت هستند و بنابراین کاملاً از یکدیگر جدا هستند. - URL های مطابق با
*.exampleusercontent.com/shim
همگی به یک فایل شیم ثابت هدایت می شوند. این فایل شیم حاوی یک قطعه کوتاه HTML و جاوا اسکریپت است که به کنترل کننده رویدادmessage
گوش می دهد و هر محتوایی را که دریافت می کند ارائه می کند. - برای استفاده از این، محصول یک iframe یا یک پنجره بازشو در
$RANDOM_VALUE.exampleusercontent.com/shim
ایجاد میکند و ازpostMessage
برای ارسال محتوای غیرقابل اعتماد به شیم برای رندر استفاده میکند. - محتوای رندر شده به یک Blob تبدیل میشود و در داخل یک iframe جعبهشنودی رندر میشود.
در مقایسه با رویکرد کلاسیک دامنه سندباکس، این تضمین میکند که تمام محتوا به طور کامل در یک سایت منحصر به فرد جدا شده است. و با داشتن برنامه اصلی با بازیابی داده هایی که باید ارائه شوند، دیگر نیازی به استفاده از URL های قابلیت نیست.
نتیجه گیری
این دو راهحل با هم، انتقال دامنههای sandbox کلاسیک مانند googleusercontent.com
را به راهحلهای امنتر که با مسدود کردن کوکیهای شخص ثالث سازگار هستند، ممکن میسازد. در Google، ما قبلاً بسیاری از محصولات را برای استفاده از این راهحلها منتقل کردهایم و برای سال آینده برنامهریزی بیشتری برای مهاجرت داریم.