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

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

อัปเดต

  • 21 มิถุนายน 2022: สคริปต์เวิร์กเกอร์ยังต้องได้รับการตรวจสอบด้วยเมื่อเปิดใช้การแยกแหล่งที่มาหลายแหล่ง เพิ่มคำอธิบายบางส่วน
  • 5 ส.ค. 2021: JS Self-Profiling API ได้รับการกล่าวถึงเป็นหนึ่งใน API ที่ต้องใช้การแยกแหล่งที่มาข้าม แต่เราได้นําออกแล้วเพื่อสอดคล้องกับการเปลี่ยนแปลงล่าสุดของแนวทาง
  • 6 พฤษภาคม 2021: จากความคิดเห็นและปัญหาที่รายงานเข้ามา เราจึงตัดสินใจปรับเวลาสำหรับการใช้งาน SharedArrayBuffer ในเว็บไซต์ที่ไม่ได้แยกแบบข้ามต้นทางเพื่อจำกัดการใช้งานใน Chrome M92
  • 16 เมษายน 2021: เพิ่มหมายเหตุเกี่ยวกับโหมดแบบไม่มีข้อมูลเข้าสู่ระบบของ COEP ใหม่และ COOP ให้มีเงื่อนไขที่ผ่อนปรนสำหรับการแสดงป๊อปอัปจากแหล่งที่มาเดียวกันเพื่อแยกแหล่งที่มา
  • 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 บัฟเฟอร์อาร์เรย์ที่ใช้ร่วมกันใน 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 ไมโครวินาทีขึ้นไป
ฟีเจอร์ที่จะพร้อมใช้งานในสถานะแยกต่างหากแบบข้ามต้นทาง

สถานะการแยกแบบข้ามต้นทางยังป้องกันไม่ให้แก้ไข 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 แล้ว

ตรวจสอบว่าทรัพยากรทั้งหมดในหน้าเว็บโหลดด้วยส่วนหัว CORP หรือ CORS HTTP ขั้นตอนนี้จำเป็นสำหรับขั้นตอนที่ 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> ฯลฯ

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

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

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

4. เปิดใช้ COEP

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

ตรวจสอบว่าแยกสำเร็จหรือไม่ด้วย 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 report เมื่อมีการบล็อกทรัพยากรข้ามแหล่งที่มาจะมีลักษณะดังนี้

[{
  "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 report เมื่อเปิดหน้าต่างป๊อปอัปแยกต่างหากมีลักษณะดังนี้

[{
  "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

แหล่งข้อมูล