ทำให้เว็บไซต์ของคุณ "มีการแยกแบบข้ามต้นทาง" โดยใช้ 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 เดียวกัน ดังนั้น ระบบจะบังคับใช้การแยกสำหรับหน้าต่างที่เปิดและปิดใช้การสื่อสารร่วมกันระหว่างหน้าต่างทั้ง 2 บาน

กลุ่มบริบทการท่องเว็บคือชุดหน้าต่างที่อ้างอิงถึงกันได้ เช่น เอกสารระดับบนสุดและเอกสารย่อยที่ฝังด้วย <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
  • สำหรับเอกสารหรือ Worker ที่แสดงผลด้วย 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 และสคริปต์ Worker ดูข้อมูลเกี่ยวกับส่วนหัว HTTP ของ Report-Only ได้ที่ สังเกตปัญหาโดยใช้ Reporting API

4. เปิดใช้ COEP

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

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

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

พร็อพเพอร์ตี้ 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.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 เพื่อดูว่าหน้าเว็บอยู่ในสถานะที่มีการแยกแบบข้ามต้นทางหรือไม่

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

แหล่งข้อมูล

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

  • 21 มิถุนายน 2022: สคริปต์ Worker ก็ต้องได้รับการดูแลด้วยเมื่อเปิดใช้การแยกแบบข้ามต้นทาง เพิ่มคำอธิบายบางส่วน
  • 5 ส.ค. 2021: เราได้กล่าวถึง JS Self-Profiling 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 ใน Android Chrome จะพร้อมใช้งานตั้งแต่ Chrome 88 เป็นต้นไป