ทำให้เว็บไซต์ของคุณ "มีการแยกแบบข้ามต้นทาง" โดยใช้ COOP และ COEP

ใช้ COOP และ COEP เพื่อตั้งค่าสภาพแวดล้อมที่มีการแยกแบบข้ามต้นทางและเปิดใช้ฟีเจอร์ที่มีประสิทธิภาพ เช่น SharedArrayBuffer, performance.measureUserAgentSpecificMemory() และตัวจับเวลาความละเอียดสูงที่มีความแม่นยำมากขึ้น

เผยแพร่เมื่อวันที่ 13 เมษายน 2020 อัปเดตล่าสุดเมื่อวันที่ 21 มิถุนายน 2022

เอกสารนี้แสดงวิธีใช้ COOP และ COEP เหล่านี้ อ่านข้อมูลเพิ่มเติมเกี่ยวกับความสำคัญของเรื่องนี้ได้ในทำให้เว็บไซต์ "มีการแยกแบบข้ามต้นทาง" โดยใช้ COOP และ COEP

Web API บางรายการเพิ่มความเสี่ยงของการโจมตีแบบ Side-channel เช่น Spectre เพื่อลดความเสี่ยงดังกล่าว เบราว์เซอร์จึงมีสภาพแวดล้อมแบบแยกที่อิงตามการเลือกใช้ ซึ่งเรียกว่ามีการแยกแบบข้ามต้นทาง เมื่อมีสถานะที่มีการแยกแบบข้ามต้นทาง หน้าเว็บจะใช้ฟีเจอร์ที่ได้รับสิทธิ์ได้ ซึ่งรวมถึงฟีเจอร์ต่อไปนี้

API คำอธิบาย
SharedArrayBuffer จำเป็นสำหรับเทรด WebAssembly ซึ่งพร้อมใช้งานตั้งแต่ Android Chrome 88 เป็นต้นไป เวอร์ชันเดสก์ท็อปจะเปิดใช้โดยค่าเริ่มต้นด้วยความช่วยเหลือจากการแยกเว็บไซต์ แต่จะต้องใช้สถานะที่มีการแยกแบบข้ามต้นทางและจะปิดใช้โดยค่าเริ่มต้นใน Chrome 92
performance.measureUserAgentSpecificMemory() พร้อมใช้งานตั้งแต่ Chrome 89
performance.now() performance.timeOrigin พร้อมใช้งานในเบราว์เซอร์หลายรายการ โดยมีความละเอียดจำกัดอยู่ที่ 100 ไมโครวินาทีขึ้นไป เมื่อมีการแยกแบบข้ามต้นทาง ความละเอียดจะอยู่ที่ 5 ไมโครวินาทีขึ้นไป
ฟีเจอร์ที่จะพร้อมใช้งานหลังสถานะมีการแยกแบบข้ามต้นทาง

สถานะที่มีการแยกแบบข้ามต้นทางยังป้องกันการแก้ไข document.domain ด้วย (การแก้ไข document.domain ได้ช่วยให้เอกสารในเว็บไซต์เดียวกันสื่อสารกันได้ และถือเป็นช่องโหว่ในนโยบายต้นทางเดียวกัน)

หากต้องการเลือกใช้สถานะที่มีการแยกแบบข้ามต้นทาง คุณต้องส่งส่วนหัว HTTP ต่อไปนี้ในเอกสารหลัก

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

ส่วนหัวเหล่านี้จะสั่งให้เบราว์เซอร์บล็อกการโหลดทรัพยากรหรือ iframe ที่ไม่ได้เลือกให้โหลดโดยเอกสารแบบข้ามต้นทาง และป้องกันไม่ให้หน้าต่างแบบข้ามต้นทางโต้ตอบกับเอกสารของคุณโดยตรง ซึ่งหมายความว่าทรัพยากรที่โหลดแบบข้ามต้นทางจะต้องมีการเลือกใช้ด้วย

คุณตรวจสอบได้ว่าหน้าเว็บอยู่ในสถานะที่มีการแยกแบบข้ามต้นทางหรือไม่โดยตรวจสอบ self.crossOriginIsolated

อภิธานศัพท์

เอกสารนี้ใช้คำศัพท์ที่มีชื่อและตัวย่อคล้ายกันหลายคำ เราได้รวบรวมอภิธานศัพท์ฉบับย่อเพื่ออธิบายความหมายของคำต่างๆ ดังนี้

ทำให้เว็บไซต์มีการแยกแบบข้ามต้นทาง

1. ตั้งค่า Cross-Origin-Opener-Policy: same-origin ในเอกสารระดับบนสุด

การเปิดใช้ COOP: same-origin ในเอกสารระดับบนสุดจะทำให้หน้าต่างที่มีต้นทางเดียวกันและหน้าต่างที่เปิดจากเอกสารมีกลุ่มบริบทการท่องเว็บแยกต่างหาก เว้นแต่จะอยู่ในต้นทางเดียวกันที่มีการตั้งค่า COOP เดียวกัน ดังนั้น ระบบจะบังคับใช้การแยกหน้าต่างที่เปิดอยู่และปิดใช้การสื่อสารร่วมกันระหว่างหน้าต่างทั้งสอง

กลุ่มบริบทการท่องเว็บคือชุดหน้าต่างที่อ้างอิงถึงกันได้ เช่น เอกสารระดับบนสุดและเอกสารย่อยที่ฝังด้วย <iframe> หากเว็บไซต์ (https://a.example) เปิดหน้าต่างกล่องโต้ตอบ (https://b.example) หน้าต่างที่เปิดและหน้าต่างกล่องโต้ตอบจะใช้บริบทการท่องเว็บเดียวกัน ดังนั้นหน้าต่างทั้งสองจึงเข้าถึงกันและกันได้ด้วย DOM API เช่น window.opener

ภาพแสดงกลุ่มเนื้อหาการท่องเว็บที่มีผู้ใช้โต้ตอบกับองค์ประกอบของหน้า

คุณสามารถตรวจสอบได้ว่าตัวเปิดหน้าต่างและตัวที่ถูกเปิดอยู่ในกลุ่มบริบทการท่องเว็บที่แยกกันหรือไม่จากเครื่องมือสำหรับนักพัฒนาเว็บ

2. เปิดใช้ CORP หรือ CORS ในทรัพยากร

ตรวจสอบว่าทรัพยากรทั้งหมดในหน้าเว็บโหลดด้วยส่วนหัว HTTP ของ CORP หรือ CORS ขั้นตอนนี้จำเป็นสำหรับขั้นตอนที่ 4 ซึ่งเป็นการเปิดใช้ COEP

สิ่งที่คุณต้องทำมีดังนี้ โดยขึ้นอยู่กับลักษณะของแหล่งข้อมูล

  • หากคาดว่าทรัพยากรจะโหลดจากต้นทางเดียวกันเท่านั้น ให้ตั้งค่าส่วนหัว Cross-Origin-Resource-Policy: same-origin
  • หากคาดว่าจะมีการโหลดทรัพยากรจากเว็บไซต์เดียวกันแต่ข้ามต้นทางเท่านั้น ให้ตั้งค่าส่วนหัว Cross-Origin-Resource-Policy: same-site
  • หากทรัพยากรโหลดจากหลายต้นทางภายใต้การควบคุมของคุณ ให้ตั้งค่าส่วนหัว Cross-Origin-Resource-Policy: cross-origin หากเป็นไปได้
  • สำหรับทรัพยากรแบบข้ามต้นทางที่คุณควบคุมไม่ได้ ให้ทำดังนี้
    • ใช้แอตทริบิวต์ crossorigin ในแท็ก HTML ที่โหลดหากมีการแสดงทรัพยากรด้วย CORS (เช่น <img src="***" crossorigin>)
    • ขอให้เจ้าของทรัพยากรรองรับ CORS หรือ CORP
  • สำหรับ iframe ให้ทำตามหลักการเดียวกันและตั้งค่า Cross-Origin-Resource-Policy: cross-origin (หรือ same-site, same-origin ขึ้นอยู่กับบริบท)
  • สคริปต์ที่โหลดด้วย WebWorker ต้องแสดงจากต้นทางเดียวกัน คุณจึงไม่จำเป็นต้องใช้ส่วนหัว CORP หรือ CORS
  • สำหรับเอกสารหรือผู้ปฏิบัติงานที่แสดงด้วย COEP: require-corp ทรัพยากรย่อยแบบข้ามต้นทางที่โหลดโดยไม่มี CORS ต้องตั้งค่าส่วนหัว Cross-Origin-Resource-Policy: cross-origin เพื่อเลือกใช้การฝัง ตัวอย่างเช่น ข้อกำหนดนี้มีผลกับ <script>, importScripts, <link>, <video>, <iframe> ฯลฯ

การแยกใน iframe

คุณสามารถเปิดใช้การแยกแบบข้ามต้นทางในเอกสารที่ฝังภายใน iframe ได้โดยใช้นโยบายสิทธิ์ allow="cross-origin-isolated" กับแท็ก <iframe> และปฏิบัติตามเงื่อนไขต่อไปนี้ เชนเอกสารทั้งหมด ซึ่งรวมถึงเฟรมหลักและเฟรมย่อย ต้องมีการแยกแบบข้ามต้นทางด้วย

3. ใช้ส่วนหัว HTTP ของ COEP Report-Only เพื่อประเมินทรัพยากรที่ฝัง

ก่อนที่จะเปิดใช้ COEP อย่างเต็มรูปแบบ คุณสามารถทดลองใช้โดยใช้ส่วนหัว Cross-Origin-Embedder-Policy-Report-Only เพื่อตรวจสอบว่านโยบายใช้งานได้จริงหรือไม่ คุณจะได้รับรายงานโดยไม่บล็อกเนื้อหาที่ฝัง

ใช้สิ่งนี้ซ้ำๆ กับเอกสารทั้งหมด รวมถึงเอกสารระดับบนสุด, iframe และสคริปต์ของผู้ปฏิบัติงาน ดูข้อมูลเกี่ยวกับส่วนหัว HTTP แบบรายงานเท่านั้นได้ที่สังเกตปัญหาโดยใช้ Reporting API

4. เปิดใช้ COEP

ขั้นตอนนี้จะทำได้ก็ต่อเมื่อคุณตรวจสอบแล้วว่าทรัพยากรเปิดใช้ CORP หรือ CORS

เมื่อยืนยันแล้วว่าทุกอย่างทำงานได้และโหลดทรัพยากรทั้งหมดได้สำเร็จ ให้เปลี่ยนส่วนหัว Cross-Origin-Embedder-Policy-Report-Only เป็นส่วนหัว Cross-Origin-Embedder-Policy ที่มีค่าเดียวกันกับเอกสารทั้งหมด รวมถึงเอกสารที่ฝังด้วย iframe และสคริปต์ของผู้ปฏิบัติงาน

ตรวจสอบว่าการแยกสำเร็จหรือไม่

พร็อพเพอร์ตี้ self.crossOriginIsolated จะแสดงผล true เมื่อหน้าเว็บอยู่ในสถานะมีการแยกแบบข้ามต้นทาง และทรัพยากรและหน้าต่างทั้งหมดจะแยกออกจากกันภายในกลุ่มบริบทการท่องเว็บเดียวกัน คุณสามารถใช้ API นี้เพื่อระบุว่าคุณได้แยกกลุ่มบริบทการท่องเว็บและได้รับสิทธิ์เข้าถึงฟีเจอร์ต่างๆ เช่น performance.measureUserAgentSpecificMemory() สำเร็จหรือไม่

แก้ไขข้อบกพร่อง

คุณอาจพบปัญหาเกี่ยวกับ COOP และ COEP คุณสามารถใช้เครื่องมือสำหรับนักพัฒนาซอฟต์แวร์ของเบราว์เซอร์หรือ Reporting API เพื่อแก้ไขข้อบกพร่องได้

แก้ไขข้อบกพร่องด้วยเครื่องมือสำหรับนักพัฒนาเว็บใน Chrome

สำหรับทรัพยากรที่แสดงผลบนหน้าจอ เช่น รูปภาพ การตรวจหาปัญหา COEP นั้นค่อนข้างง่าย เนื่องจากคำขอถูกบล็อกและหน้าเว็บควรระบุว่ารูปภาพหายไป อย่างไรก็ตาม สำหรับทรัพยากรที่ไม่จำเป็นต้องมีผลกระทบต่อภาพ เช่น สคริปต์หรือสไตล์ ปัญหา COEP อาจไม่เป็นที่สังเกต สำหรับคำขอเหล่านั้น ให้ใช้แผงเครือข่ายเครื่องมือสำหรับนักพัฒนาเว็บ

หาก COEP มีปัญหา คุณจะเห็น (blocked:NotSameOriginAfterDefaultedToSameOriginByCoep) ในคอลัมน์สถานะ

ปัญหา COEP ในคอลัมน์สถานะของแผงเครือข่าย

จากนั้นคุณจะคลิกรายการเพื่อดูรายละเอียดเพิ่มเติมได้

รายละเอียดของปัญหา COEP จะแสดงในแท็บส่วนหัวหลังจากคลิกทรัพยากรเครือข่ายในแผงเครือข่าย

นอกจากนี้ คุณยังตรวจสอบสถานะของ iframe และหน้าต่างกล่องโต้ตอบผ่านแผงแอปพลิเคชันได้ด้วย ไปที่ส่วน "เฟรม" ทางด้านซ้าย แล้วขยาย "ด้านบน" เพื่อดูรายละเอียดโครงสร้างทรัพยากร

คุณสามารถตรวจสอบสถานะของ iframe เช่น ความพร้อมใช้งานของ SharedArrayBuffer เป็นต้น

เครื่องมือตรวจสอบ iframe ของเครื่องมือสำหรับนักพัฒนาเว็บใน Chrome

นอกจากนี้ คุณยังตรวจสอบสถานะของหน้าต่างกล่องโต้ตอบได้ด้วย เช่น มีการแยกแบบข้ามต้นทางหรือไม่

เครื่องมือตรวจสอบหน้าต่างกล่องโต้ตอบของเครื่องมือสำหรับนักพัฒนาเว็บใน Chrome

สังเกตปัญหาโดยใช้ Reporting API

Reporting API เป็นอีกกลไกหนึ่งที่คุณสามารถใช้ตรวจหาปัญหาต่างๆ ได้ คุณสามารถกำหนดค่า Reporting API เพื่อสั่งให้เบราว์เซอร์ของผู้ใช้ส่งรายงานเมื่อใดก็ตามที่ COEP บล็อกการโหลดทรัพยากรหรือ COOP แยกหน้าต่างกล่องโต้ตอบ Chrome รองรับ Reporting API ตั้งแต่เวอร์ชัน 69 สำหรับการใช้งานที่หลากหลาย ซึ่งรวมถึง COEP และ COOP

ดูวิธีกำหนดค่า Reporting API และตั้งค่าเซิร์ฟเวอร์เพื่อรับรายงาน

ตัวอย่างรายงาน COEP

ตัวอย่างเพย์โหลดรายงาน COEP เมื่อทรัพยากรแบบข้ามต้นทางถูกบล็อกจะมีลักษณะดังนี้

[{
  "age": 25101,
  "body": {
    "blocked-url": "https://third-party-test.example.org/check.svg?",
    "blockedURL": "https://third-party-test.example.org/check.svg?",
    "destination": "image",
    "disposition": "enforce",
    "type": "corp"
  },
  "type": "coep",
  "url": "https://cross-origin-isolation.example.com/?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.example.org/popup?report-only&coop=same-origin&",
    "type": "navigation-from-response"
  },
  "type": "coop",
  "url": "https://cross-origin-isolation.example.com/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"
}]

เมื่อกลุ่มบริบทการท่องเว็บที่แตกต่างกันพยายามเข้าถึงกัน (เฉพาะในโหมด "รายงานเท่านั้น") COOP จะส่งรายงานด้วย ตัวอย่างเช่น รายงานเมื่อมีการพยายามเข้าถึง postMessage() จะมีลักษณะดังนี้

[{
  "age": 51785,
  "body": {
    "columnNumber": 18,
    "disposition": "reporting",
    "effectivePolicy": "same-origin",
    "lineNumber": 83,
    "property": "postMessage",
    "sourceFile": "https://cross-origin-isolation.example.com/popup.js",
    "type": "access-from-coop-page-to-openee"
  },
  "type": "coop",
  "url": "https://cross-origin-isolation.example.com/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.example.com/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

แหล่งข้อมูล

การอัปเดตเอกสาร

  • 21 มิถุนายน 2022: สคริปต์ของผู้ปฏิบัติงานยังต้องได้รับการดูแลเมื่อเปิดใช้การแยกแบบข้ามต้นทาง เพิ่มคำอธิบายบางส่วน
  • 5 ส.ค. 2021: มีการพูดถึง JS Self-Profiling API ว่าเป็นหนึ่งใน API ที่ต้องมีการแยกแบบข้ามต้นทาง แต่เมื่อพิจารณาถึงการเปลี่ยนแปลงทิศทางล่าสุด เราจึงนำ API ดังกล่าวออก
  • 6 พฤษภาคม 2021: จากความคิดเห็นและปัญหาที่ได้รับรายงาน เราได้ตัดสินใจปรับไทม์ไลน์สำหรับการใช้ SharedArrayBuffer ในเว็บไซต์ที่ไม่มีการแยกแบบข้ามต้นทางให้ถูกจำกัดใน Chrome M92
  • 16 เมษายน 2021: เพิ่มหมายเหตุเกี่ยวกับโหมด COEP ที่ไม่มีข้อมูลเข้าสู่ระบบและCOOP same-origin-allow-popups เพื่อให้เป็นเงื่อนไขที่ผ่อนคลายสำหรับการแยกแบบข้ามต้นทาง
  • 5 มีนาคม 2021: นำข้อจำกัดสำหรับฟังก์ชันการทำงานของ SharedArrayBuffer, performance.measureUserAgentSpecificMemory() และการแก้ไขข้อบกพร่องออก ซึ่งตอนนี้เปิดใช้ใน Chrome 89 อย่างเต็มรูปแบบแล้ว เพิ่มความสามารถที่กำลังจะมาถึงอย่าง performance.now() และ performance.timeOrigin ซึ่งจะมีความแม่นยำสูงขึ้น
  • 19 กุมภาพันธ์ 2021: เพิ่มหมายเหตุเกี่ยวกับนโยบายฟีเจอร์ allow="cross-origin-isolated"และฟังก์ชันการแก้ไขข้อบกพร่องในเครื่องมือสำหรับนักพัฒนาเว็บ
  • 15 ตุลาคม 2020: self.crossOriginIsolated พร้อมใช้งานตั้งแต่ Chrome 87 เป็นต้นไป ซึ่งจะเห็นได้ว่า document.domain จะเปลี่ยนแปลงไม่ได้เมื่อ self.crossOriginIsolated แสดงผลเป็น true performance.measureUserAgentSpecificMemory() กำลังจะสิ้นสุดช่วงทดลองใช้จากต้นทางและเปิดใช้โดยค่าเริ่มต้นใน Chrome 89 Shared Array Buffer ใน Chrome สำหรับ Android จะพร้อมใช้งานตั้งแต่ Chrome 88 เป็นต้นไป