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

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

อัปเดต

  • 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 ใน Chrome สำหรับ Android จะ พร้อมใช้งานตั้งแต่ Chrome 88

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

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

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

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

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

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

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

บทความนี้แสดงวิธีใช้ส่วนหัวใหม่เหล่านี้ ในบทความติดตามผล ฉันจะให้ข้อมูลพื้นฐานและบริบทเพิ่มเติม

ติดตั้งใช้งาน COOP และ COEP เพื่อให้เว็บไซต์ของคุณแยกแบบข้ามต้นทาง

ผสานรวม COOP และ COEP

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> เป็นต้น

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

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

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

4. เปิดใช้ COEP

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

พิจารณาว่าการแยกสำเร็จหรือไม่ด้วย self.crossOriginIsolated

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

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

เมื่อกลุ่มบริบทการท่องเว็บที่แตกต่างกันพยายามเข้าถึงกัน (เฉพาะในโหมด "รายงานเท่านั้น" เท่านั้น) 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

แหล่งข้อมูล