میزبانی ایمن داده های کاربر در برنامه های کاربردی وب مدرن

دیوید دورکن
David Dworken

بسیاری از برنامه های کاربردی وب نیاز به نمایش محتوای کنترل شده توسط کاربر دارند. این می تواند به سادگی ارائه تصاویر آپلود شده توسط کاربر (به عنوان مثال، عکس های نمایه)، یا به پیچیدگی ارائه 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 برای فعال کردن جداسازی مبدا متقاطع تنظیم کنید.

رویکرد 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، ما قبلاً بسیاری از محصولات را برای استفاده از این راه‌حل‌ها منتقل کرده‌ایم و برای سال آینده برنامه‌ریزی بیشتری برای مهاجرت داریم.

،

دیوید دورکن
David Dworken

بسیاری از برنامه های کاربردی وب نیاز به نمایش محتوای کنترل شده توسط کاربر دارند. این می تواند به سادگی ارائه تصاویر آپلود شده توسط کاربر (به عنوان مثال، عکس های نمایه)، یا به پیچیدگی ارائه 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 برای فعال کردن جداسازی مبدا متقاطع تنظیم کنید.

رویکرد 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، ما قبلاً بسیاری از محصولات را برای استفاده از این راه‌حل‌ها منتقل کرده‌ایم و برای سال آینده برنامه‌ریزی بیشتری برای مهاجرت داریم.