با استفاده از COOP و COEP، وب‌سایت خود را «ایزوله بین‌منبعی» کنید

از COOP و COEP برای راه‌اندازی یک محیط ایزوله بین مبدایی استفاده کنید و ویژگی‌های قدرتمندی مانند SharedArrayBuffer ، performance.measureUserAgentSpecificMemory() و تایمر با وضوح بالا را با دقت بهتر فعال کنید.

منتشر شده: ۱۳ آوریل ۲۰۲۰، آخرین به‌روزرسانی: ۲۱ ژوئن ۲۰۲۲

این سند نحوه استفاده از این COOP و COEP را نشان می‌دهد. می‌توانید اطلاعات بیشتر در مورد اهمیت این موضوع را در «ایجاد وب‌سایت خود با استفاده از COOP و COEP به صورت «ایزوله بین مبدا»» مطالعه کنید.

برخی از APIهای وب، خطر حملات کانال جانبی مانند Spectre را افزایش می‌دهند. برای کاهش این خطر، مرورگرها یک محیط ایزوله مبتنی بر انتخاب به نام cross-origin isolation ارائه می‌دهند. با حالت cross-origin isolation، صفحه وب قادر به استفاده از ویژگی‌های ممتاز از جمله موارد زیر خواهد بود:

رابط برنامه‌نویسی کاربردی توضیحات
SharedArrayBuffer برای رشته‌های WebAssembly مورد نیاز است. این قابلیت از اندروید کروم ۸۸ در دسترس است. نسخه دسکتاپ به طور پیش‌فرض با کمک Site Isolation فعال است، اما به حالت ایزوله بین مبدا نیاز دارد و به طور پیش‌فرض در کروم ۹۲ غیرفعال خواهد بود .
performance.measureUserAgentSpecificMemory() از کروم ۸۹ در دسترس است.
performance.now() ، performance.timeOrigin در بسیاری از مرورگرها موجود است، با وضوح محدود به ۱۰۰ میکروثانیه یا بالاتر. با ایزولاسیون بین مبدا، وضوح می‌تواند ۵ میکروثانیه یا بالاتر باشد.
ویژگی‌هایی که در حالت ایزوله بین مبدا (cross-origin) در دسترس خواهند بود.

حالت ایزوله بین مبدایی همچنین از تغییر document.domain جلوگیری می‌کند. (قابلیت تغییر document.domain امکان ارتباط بین اسناد هم‌مکان را فراهم می‌کند و به عنوان یک راه گریز در سیاست هم‌مکانی در نظر گرفته شده است.)

برای ورود به حالت ایزوله بین مبدا، باید هدرهای HTTP زیر را در سند اصلی ارسال کنید:

Cross-Origin-Embedder-Policy: require-corp
Cross-Origin-Opener-Policy: same-origin

این هدرها به مرورگر دستور می‌دهند که بارگذاری منابع یا iframeهایی را که برای بارگذاری توسط اسناد cross-origin انتخاب نشده‌اند، مسدود کند و از تعامل مستقیم پنجره‌های cross-origin با سند شما جلوگیری کند. این همچنین به این معنی است که منابعی که به صورت cross-origin بارگذاری می‌شوند، نیاز به انتخاب دارند.

شما می‌توانید با بررسی self.crossOriginIsolated تشخیص دهید که آیا یک صفحه وب در حالت ایزوله بین مبدا (cross-origin isolation) قرار دارد یا خیر.

واژه‌نامه

این سند از بسیاری از اصطلاحات با نام‌های مشابه و اختصارات استفاده می‌کند. برای روشن شدن، ما یک واژه‌نامه کوچک تهیه کرده‌ایم:

وب‌سایت خود را به صورت چند-مبدأی ایزوله کنید

۱. تنظیم Cross-Origin-Opener-Policy: same-origin روی سند سطح بالا

با فعال کردن COOP: same-origin در یک سند سطح بالا، پنجره‌هایی با منشأ یکسان و پنجره‌هایی که از سند باز شده‌اند، یک گروه زمینه مرور جداگانه دارند، مگر اینکه در منشأ یکسانی با تنظیمات COOP یکسان باشند. بنابراین، جداسازی برای پنجره‌های باز اعمال می‌شود و ارتباط متقابل بین هر دو پنجره غیرفعال می‌شود.

یک گروه زمینه مرور، مجموعه‌ای از پنجره‌ها است که می‌توانند به یکدیگر ارجاع دهند. برای مثال، یک سند سطح بالا و اسناد فرزند آن که با <iframe> جاسازی شده‌اند. اگر یک وب‌سایت ( https://a.example ) یک پنجره محاوره‌ای ( https://b.example ) باز کند، پنجره بازکننده و پنجره محاوره‌ای، زمینه مرور یکسانی را به اشتراک می‌گذارند، بنابراین آنها با APIهای DOM مانند window.opener به یکدیگر دسترسی دارند.

تصویری که گروه محتوای در حال مرور را به همراه تعامل کاربر با عناصر صفحه نشان می‌دهد.

می‌توانید بررسی کنید که آیا بازکننده‌ی پنجره و بازشونده‌ی آن در گروه‌های زمینه‌ی مرور جداگانه‌ای از DevTools قرار دارند یا خیر.

۲. فعال کردن CORP یا CORS روی منابع

مطمئن شوید که تمام منابع موجود در صفحه با هدرهای CORP یا CORS HTTP بارگذاری شده‌اند. این مرحله برای مرحله چهارم، فعال کردن COEP ، ضروری است.

بسته به ماهیت منبع، کارهایی که باید انجام دهید به شرح زیر است:

  • اگر انتظار می‌رود منبع فقط از همان مبدا بارگیری شود، هدر Cross-Origin-Resource-Policy: same-origin را تنظیم کنید.
  • اگر انتظار می‌رود منبع فقط از همان سایت اما با منشاء متقابل بارگیری شود، هدر Cross-Origin-Resource-Policy: same-site تنظیم کنید.
  • اگر منبع از cross origin(s) تحت کنترل شما بارگذاری می‌شود، در صورت امکان هدر Cross-Origin-Resource-Policy: cross-origin را تنظیم کنید.
  • برای منابع چندمنبعی که هیچ کنترلی روی آنها ندارید:
    • اگر منبع با CORS ارائه می‌شود، از ویژگی crossorigin در تگ بارگذاری HTML استفاده کنید. (برای مثال، <img src="***" crossorigin> ).
    • از صاحب منبع بخواهید که از CORS یا CORP پشتیبانی کند.
  • برای iframeها، از همین اصول پیروی کنید و Cross-Origin-Resource-Policy: cross-origin (یا same-site ، same-origin بسته به متن) تنظیم کنید.
  • اسکریپت‌هایی که با WebWorker بارگذاری می‌شوند باید از همان مبدا ارائه شوند، بنابراین به هدرهای CORP یا CORS نیازی ندارید.
  • برای یک سند یا ورکر که با COEP: require-corp ارائه می‌شود، زیرمنابع cross-origin که بدون CORS بارگذاری می‌شوند، باید هدر Cross-Origin-Resource-Policy: cross-origin را طوری تنظیم کنند که قابلیت جاسازی داشته باشد. برای مثال، این مورد در مورد <script> ، importScripts ، <link> ، <video> ، <iframe> و غیره صدق می‌کند.

جداسازی در iframe ها

شما می‌توانید با اعمال سیاست مجوزهای allow="cross-origin-isolated" به تگ <iframe> و برآورده کردن این شرایط، ایزولاسیون بین مبدا را روی سندی که درون یک iframe جاسازی شده است، فعال کنید. کل زنجیره اسناد، شامل فریم‌های والد و فریم‌های فرزند، نیز باید ایزولاسیون بین مبدا داشته باشند.

۳. از هدر HTTP مربوط به COEP Report-Only برای ارزیابی منابع تعبیه‌شده استفاده کنید.

قبل از فعال‌سازی کامل COEP، می‌توانید با استفاده از هدر Cross-Origin-Embedder-Policy-Report-Only یک آزمایش عملی انجام دهید تا بررسی کنید که آیا این سیاست واقعاً کار می‌کند یا خیر. گزارش‌ها را بدون مسدود کردن محتوای جاسازی‌شده دریافت خواهید کرد.

این را به صورت بازگشتی روی همه اسناد از جمله سند سطح بالا، iframe ها و اسکریپت‌های worker اعمال کنید. برای اطلاعات بیشتر در مورد هدر HTTP فقط برای گزارش، به بخش «مسائل مربوط به استفاده از Reporting API» مراجعه کنید.

۴. فعال کردن COEP

این مرحله فقط زمانی قابل انجام است که مطمئن شوید منابع CORP یا CORS را فعال کرده‌اند .

وقتی مطمئن شدید که همه چیز کار می‌کند و همه منابع با موفقیت بارگذاری می‌شوند، هدر Cross-Origin-Embedder-Policy-Report-Only را به هدر Cross-Origin-Embedder-Policy تغییر دهید و مقدار آن را برای همه اسناد، از جمله اسنادی که با iframeها و اسکریپت‌های worker جاسازی شده‌اند، یکسان کنید.

تعیین اینکه آیا جداسازی موفقیت‌آمیز بوده است یا خیر

ویژگی self.crossOriginIsolated زمانی true را برمی‌گرداند که صفحه وب در حالت ایزوله بین مبدا (cross-origin) باشد و همه منابع و پنجره‌ها در یک گروه زمینه مرور (browsing context group) ایزوله شده باشند. می‌توانید از این API برای تعیین اینکه آیا با موفقیت گروه زمینه مرور را ایزوله کرده‌اید و به ویژگی‌هایی مانند performance.measureUserAgentSpecificMemory() دسترسی پیدا کرده‌اید یا خیر، استفاده کنید.

مشکلات اشکال‌زدایی

ممکن است با مشکلاتی در COOP و COEP مواجه شوید. می‌توانید از ابزارهای توسعه‌دهنده مرورگر یا API گزارش‌دهی برای اشکال‌زدایی استفاده کنید.

اشکال‌زدایی با ابزارهای توسعه کروم

برای منابعی که روی صفحه نمایش داده می‌شوند، مانند تصاویر، تشخیص مشکلات COEP نسبتاً آسان است، زیرا درخواست مسدود شده است و صفحه باید یک تصویر از دست رفته را نشان دهد. با این حال، برای منابعی که لزوماً تأثیر بصری ندارند، مانند اسکریپت‌ها یا استایل‌ها، مشکلات COEP ممکن است مورد توجه قرار نگیرند. برای این موارد، از پنل DevTools Network استفاده کنید.

اگر مشکلی با COEP وجود داشته باشد، باید (blocked:NotSameOriginAfterDefaultedToSameOriginByCoep) را در ستون وضعیت مشاهده کنید.

مشکلات COEP در ستون وضعیت پنل شبکه.

سپس می‌توانید برای مشاهده جزئیات بیشتر، روی ورودی کلیک کنید.

جزئیات مشکل COEP پس از کلیک روی یک منبع شبکه در پنل Network، در تب Headers نمایش داده می‌شود.

همچنین می‌توانید وضعیت iframeها و پنجره‌های محاوره‌ای را از طریق پنل Application تعیین کنید. به بخش "Frames" در سمت چپ بروید و "top" را باز کنید تا جزئیات ساختار منابع را مشاهده کنید.

می‌توانید وضعیت iframe مانند در دسترس بودن SharedArrayBuffer و غیره را بررسی کنید.

بازرس iframe Chrome DevTools.

همچنین می‌توانید وضعیت پنجره‌های محاوره‌ای را بررسی کنید، مثلاً اینکه آیا ایزوله بین مبدا (cross-origin) است یا خیر.

بازرس پنجره محاوره‌ای Chrome DevTools

مشاهده مشکلات با استفاده از Reporting API

API گزارش‌دهی (Reporting API) مکانیزم دیگری است که از طریق آن می‌توانید مشکلات مختلف را تشخیص دهید. می‌توانید API گزارش‌دهی را طوری پیکربندی کنید که به مرورگر کاربران خود دستور دهد هر زمان که COEP بارگذاری یک منبع را مسدود کرد یا COOP یک پنجره محاوره‌ای را ایزوله کرد، گزارشی ارسال کند. کروم از نسخه ۶۹ از API گزارش‌دهی برای کاربردهای متنوعی از جمله COEP و COOP پشتیبانی می‌کند.

یاد بگیرید که چگونه Reporting API را پیکربندی کنید و یک سرور برای دریافت گزارش‌ها راه‌اندازی کنید.

نمونه گزارش COEP

یک نمونه از بار داده گزارش COEP هنگام مسدود شدن منبع بین مبدائی به این شکل است:

[{
  "age": 25101,
  "body": {
    "blocked-url": "https://third-party-test.glitch.me/check.svg?",
    "blockedURL": "https://third-party-test.glitch.me/check.svg?",
    "destination": "image",
    "disposition": "enforce",
    "type": "corp"
  },
  "type": "coep",
  "url": "https://cross-origin-isolation.glitch.me/?coep=require-corp&coop=same-origin&",
  "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4249.0 Safari/537.36"
}]

نمونه گزارش COOP

یک نمونه از بار داده گزارش COOP هنگام باز شدن یک کادر محاوره‌ای به صورت ایزوله، چیزی شبیه به این است:

[{
  "age": 7,
  "body": {
    "disposition": "enforce",
    "effectivePolicy": "same-origin",
    "nextResponseURL": "https://third-party-test.glitch.me/popup?report-only&coop=same-origin&",
    "type": "navigation-from-response"
  },
  "type": "coop",
  "url": "https://cross-origin-isolation.glitch.me/coop?coop=same-origin&",
  "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4246.0 Safari/537.36"
}]

وقتی گروه‌های مختلف زمینه مرور سعی می‌کنند به یکدیگر دسترسی پیدا کنند (فقط در حالت "report-only")، COOP همچنین گزارشی ارسال می‌کند. برای مثال، گزارشی که هنگام تلاش برای postMessage() ارسال می‌شود، به این شکل خواهد بود:

[{
  "age": 51785,
  "body": {
    "columnNumber": 18,
    "disposition": "reporting",
    "effectivePolicy": "same-origin",
    "lineNumber": 83,
    "property": "postMessage",
    "sourceFile": "https://cross-origin-isolation.glitch.me/popup.js",
    "type": "access-from-coop-page-to-openee"
  },
  "type": "coop",
  "url": "https://cross-origin-isolation.glitch.me/coop?report-only&coop=same-origin&",
  "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4246.0 Safari/537.36"
},
{
  "age": 51785,
  "body": {
    "disposition": "reporting",
    "effectivePolicy": "same-origin",
    "property": "postMessage",
    "type": "access-to-coop-page-from-openee"
  },
  "type": "coop",
  "url": "https://cross-origin-isolation.glitch.me/coop?report-only&coop=same-origin&",
  "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4246.0 Safari/537.36"
}]

غذاهای بیرون‌بر

از ترکیبی از هدرهای HTTP COOP و COEP برای قرار دادن یک صفحه وب در حالت ایزوله بین مبدائی خاص استفاده کنید. می‌توانید self.crossOriginIsolated بررسی کنید تا مشخص شود که آیا یک صفحه وب در حالت ایزوله بین مبدائی قرار دارد یا خیر.

با در دسترس قرار گرفتن ویژگی‌های جدید برای این حالت ایزوله بین مبدا و بهبودهای بیشتر در DevTools پیرامون COOP و COEP، این پست را به‌روزرسانی خواهیم کرد .

منابع

به‌روزرسانی‌های سند

  • ۲۱ ژوئن ۲۰۲۲ : اسکریپت‌های Worker نیز هنگام فعال بودن جداسازی بین مبدا نیاز به مراقبت دارند. توضیحاتی اضافه شد.
  • ۵ آگوست ۲۰۲۱ : API خود-پروفایل‌سازی JS به عنوان یکی از APIهایی که نیاز به جداسازی بین مبدایی دارند، ذکر شده بود، اما با توجه به تغییر اخیر مسیر ، این مورد حذف شده است.
  • ۶ مه ۲۰۲۱ : بر اساس بازخوردها و مشکلات گزارش‌شده، تصمیم گرفتیم جدول زمانی استفاده از SharedArrayBuffer را در سایت‌های غیرمتمرکز در Chrome M92 محدود کنیم.
  • ۱۶ آوریل ۲۰۲۱ : نکاتی در مورد حالت بدون اعتبار COEP و حالت بازشوهای با منشاء یکسان COOP به عنوان یک شرط آسان برای جداسازی بین مبدائی اضافه شد.
  • ۵ مارس ۲۰۲۱ : محدودیت‌های SharedArrayBuffer ، performance.measureUserAgentSpecificMemory() و قابلیت‌های اشکال‌زدایی که اکنون به‌طور کامل در Chrome ۸۹ فعال شده‌اند، حذف شد. قابلیت‌های آینده، performance.now() و performance.timeOrigin که دقت بالاتری خواهند داشت، اضافه شدند.
  • ۱۹ فوریه ۲۰۲۱ : یادداشتی در مورد سیاست ویژگی allow="cross-origin-isolated" و عملکرد اشکال‌زدایی در DevTools اضافه شد.
  • ۱۵ اکتبر ۲۰۲۰ : self.crossOriginIsolated از کروم ۸۷ در دسترس است. با توجه به این موضوع، document.domain زمانی که self.crossOriginIsolated true را برمی‌گرداند، تغییرناپذیر است. performance.measureUserAgentSpecificMemory() در حال پایان دادن به دوره آزمایشی اولیه خود است و به طور پیش‌فرض در کروم ۸۹ فعال است. Shared Array Buffer در کروم اندروید از کروم ۸۸ در دسترس خواهد بود.