ดูสาเหตุที่จําเป็นต้องใช้การแยกแบบข้ามต้นทางเพื่อใช้ฟีเจอร์ที่มีประสิทธิภาพ เช่น SharedArrayBuffer
, performance.measureUserAgentSpecificMemory()
และตัวจับเวลาความละเอียดสูงที่แม่นยํามากขึ้น
เกริ่นนำ
ในส่วนการทำให้เว็บไซต์ "แยกแบบข้ามต้นทาง" โดยใช้ COOP และ COEP เราได้อธิบายวิธีปรับใช้สถานะ "แยกแบบข้ามต้นทาง" โดยใช้ COOP และ COEP นี่เป็นบทความที่แสดงร่วมกันซึ่งอธิบายเหตุผลที่ต้องใช้การแยกแบบข้ามต้นทางเพื่อเปิดใช้ฟีเจอร์ที่มีประสิทธิภาพในเบราว์เซอร์
ที่มา
เว็บสร้างขึ้นด้วยนโยบายต้นทางเดียวกัน ซึ่งเป็นฟีเจอร์ความปลอดภัยที่จำกัดวิธีที่เอกสารและสคริปต์จะโต้ตอบกับทรัพยากรจากต้นทางอื่นได้ หลักการนี้จำกัดวิธีที่เว็บไซต์จะเข้าถึงทรัพยากรแบบข้ามต้นทางได้ เช่น ระบบป้องกันไม่ให้เอกสารจาก https://a.example
เข้าถึงข้อมูลที่โฮสต์ไว้ที่ https://b.example
อย่างไรก็ตาม นโยบายต้นทางเดียวกันมีข้อยกเว้นในอดีต เว็บไซต์ใดๆ สามารถทำสิ่งต่อไปนี้ได้
- ฝัง iframe แบบข้ามต้นทาง
- รวมทรัพยากรแบบข้ามต้นทาง เช่น รูปภาพหรือสคริปต์
- เปิดหน้าต่างป๊อปอัปข้ามต้นทางที่มีการอ้างอิง DOM
หากออกแบบเว็บได้ใหม่ตั้งแต่ต้น ก็จะไม่มีข้อยกเว้นเหล่านี้ แต่เมื่อถึงเวลาที่ชุมชนเว็บทราบถึงประโยชน์หลักๆ ของนโยบายที่มีต้นทางเดียวกัน เว็บก็อาศัยข้อยกเว้นเหล่านี้อยู่แล้ว
การแพตช์ผลข้างเคียงด้านความปลอดภัยของนโยบายต้นทางเดียวกันที่ผ่อนปรนดังกล่าวแบ่งออกเป็น 2 ทาง วิธีหนึ่งคือการเปิดตัวโปรโตคอลใหม่ชื่อ cross
Origin Resource Share (CORS)
ที่มีจุดประสงค์คือตรวจสอบว่าเซิร์ฟเวอร์อนุญาตให้แชร์ทรัพยากรกับต้นทางที่กำหนดได้ อีกวิธีหนึ่งคือการนำการเข้าถึงสคริปต์โดยตรงออกจากทรัพยากรแบบข้ามต้นทางโดยปริยายโดยที่ยังรักษาความเข้ากันได้แบบย้อนหลังไว้ ทรัพยากรข้ามต้นทางดังกล่าวเรียกว่าทรัพยากรที่ "คลุมเครือ" เช่น สาเหตุที่ทำให้การควบคุมพิกเซลของรูปภาพแบบข้ามต้นทางผ่าน CanvasRenderingContext2D
ไม่สำเร็จ เว้นแต่ว่าจะมีการใช้ CORS กับรูปภาพ
การตัดสินใจเกี่ยวกับนโยบายเหล่านี้ทั้งหมดจะเกิดขึ้นภายในกลุ่มบริบทของการท่องเว็บ
การใช้ CORS และทรัพยากรที่ไม่ชัดเจนอยู่รวมกันก็เพียงพอที่จะทำให้เบราว์เซอร์ปลอดภัย ในบางครั้ง อาจมีกรณี Edge Case (เช่น ช่องโหว่ JSON) และจำเป็นต้องแพตช์ แต่โดยรวมแล้วหลักการการไม่อนุญาตสิทธิ์การอ่านโดยตรงของไบต์ดิบของทรัพยากรแบบข้ามต้นทางประสบความสำเร็จ
ทั้งหมดนี้เปลี่ยนไปด้วย Spectre ซึ่งทำให้ข้อมูลที่โหลดขึ้นในกลุ่มบริบทการท่องเว็บเดียวกันกับโค้ดที่อาจอ่านได้ ด้วยการวัดเวลาที่ใช้ในการดำเนินการบางอย่าง ผู้โจมตีจะสามารถคาดเดาเนื้อหาของแคช CPU และเนื้อหาในหน่วยความจำของกระบวนการได้ การโจมตีตามจังหวะเวลาในลักษณะดังกล่าวเป็นไปได้ด้วยตัวจับเวลาแบบละเอียดต่ำที่มีอยู่ในแพลตฟอร์ม แต่สามารถเร่งความเร็วด้วยตัวจับเวลาที่มีความละเอียดสูง ทั้งแบบโจ่งแจ้ง (เช่น performance.now()
) และโดยนัย (เช่น SharedArrayBuffer
) หาก evil.com
ฝังอิมเมจแบบข้ามต้นทาง ก็จะใช้การโจมตี Spectre เพื่ออ่านข้อมูลพิกเซลได้ ซึ่งทำให้การป้องกันที่อาศัย "ความทึบแสง" ไม่มีประสิทธิภาพ
ตามหลักการแล้ว คำขอข้ามต้นทางทั้งหมดควรได้รับการตรวจสอบอย่างชัดแจ้งโดยเซิร์ฟเวอร์ที่เป็นเจ้าของทรัพยากร หากเซิร์ฟเวอร์ที่เป็นเจ้าของทรัพยากรไม่ได้ทำการตรวจสอบ ข้อมูลจะไม่เข้าไปอยู่ในกลุ่มบริบทการท่องเว็บของตัวร้ายกาจ และจะไม่สามารถหลบเลี่ยงการโจมตีจากสเปคเตอร์ที่หน้าเว็บทำได้ ซึ่งเราเรียกว่าสถานะการแยกแบบข้ามต้นทาง และนี่คือเนื้อหาของ COOP+COEP
ภายใต้สถานะที่แยกออกมาแบบข้ามต้นทาง จะถือว่าเว็บไซต์ที่ส่งคำขอเป็นอันตรายน้อยกว่าและจะปลดล็อกฟีเจอร์ที่มีประสิทธิภาพ เช่น SharedArrayBuffer
, performance.measureUserAgentSpecificMemory()
และตัวจับเวลาความละเอียดสูงที่มีความแม่นยำมากกว่า ซึ่งในกรณีอื่นๆ อาจนำมาใช้กับการโจมตีแบบสเปกเตอร์ได้ และยังทำให้แก้ไข document.domain
ไม่ได้ด้วย
นโยบายเครื่องมือฝังแบบข้ามต้นทาง
นโยบายเครื่องมือฝังแบบข้ามต้นทาง (COEP) ป้องกันไม่ให้เอกสารโหลดทรัพยากรแบบข้ามต้นทางที่ไม่ได้ให้สิทธิ์แก่เอกสารอย่างชัดเจน (โดยใช้ CORP หรือ CORS) ฟีเจอร์นี้ช่วยให้คุณประกาศว่าเอกสารโหลดทรัพยากรดังกล่าวไม่ได้
หากต้องการเปิดใช้งานนโยบายนี้ ให้เพิ่มส่วนหัว HTTP ต่อไปนี้ต่อท้ายเอกสาร
Cross-Origin-Embedder-Policy: require-corp
คีย์เวิร์ด require-corp
เป็นค่าเดียวที่ยอมรับสำหรับ COEP การดำเนินการนี้จะบังคับใช้นโยบายที่ว่าเอกสารจะโหลดได้เฉพาะทรัพยากรจากต้นทางเดียวกัน หรือทรัพยากรที่ทำเครื่องหมายอย่างชัดเจนว่าโหลดได้จากต้นทางอื่น
หากต้องการให้ทรัพยากรโหลดได้จากต้นทางอื่น ทรัพยากรจะต้องรองรับกลไกการแชร์ทรัพยากรข้ามโดเมน (CORS) หรือนโยบายทรัพยากรข้ามโดเมน (CORP)
กลไกการแชร์ทรัพยากรข้ามโดเมน
หากทรัพยากรแบบข้ามต้นทางรองรับการแชร์ทรัพยากรข้ามต้นทาง
(CORS) คุณอาจใช้
แอตทริบิวต์ crossorigin
เพื่อโหลดไปยังหน้าเว็บโดยไม่ถูกบล็อกโดย COEP
<img src="https://third-party.example.com/image.jpg" crossorigin>
ตัวอย่างเช่น หากทรัพยากรรูปภาพนี้ให้บริการพร้อมส่วนหัว CORS ให้ใช้แอตทริบิวต์ crossorigin
เพื่อให้คำขอดึงข้อมูลทรัพยากรใช้โหมด CORS และยังป้องกันไม่ให้มีการโหลดรูปภาพ เว้นแต่จะตั้งค่าส่วนหัว CORS
ในทำนองเดียวกัน คุณอาจดึงข้อมูลข้ามต้นทางผ่านเมธอด fetch()
ซึ่งไม่จำเป็นต้องมีการจัดการพิเศษตราบใดที่เซิร์ฟเวอร์ตอบสนองด้วยส่วนหัว HTTP ที่ถูกต้อง
นโยบายทรัพยากรข้ามโดเมน
นโยบายทรัพยากรข้ามโดเมน (CORP) เดิมนำมาใช้เป็นการเลือกใช้เพื่อป้องกันไม่ให้ต้นทางอื่นโหลดทรัพยากรของคุณ ในบริบทของ COEP นั้น CORP สามารถระบุนโยบายของเจ้าของทรัพยากรว่าใครสามารถโหลดทรัพยากร
ส่วนหัว Cross-Origin-Resource-Policy
มีค่าที่เป็นไปได้ 3 ค่า ได้แก่
Cross-Origin-Resource-Policy: same-site
ทรัพยากรที่มีเครื่องหมาย same-site
จะโหลดจากเว็บไซต์เดียวกันเท่านั้น
Cross-Origin-Resource-Policy: same-origin
ทรัพยากรที่มีการทำเครื่องหมาย same-origin
จะโหลดจากต้นทางเดียวกันได้เท่านั้น
Cross-Origin-Resource-Policy: cross-origin
ทรัพยากรที่มีเครื่องหมาย cross-origin
สามารถโหลดขึ้นในเว็บไซต์ใดก็ได้ (มีการเพิ่มค่านี้ลงในข้อกำหนดเฉพาะของ CORP พร้อมกับ COEP)
นโยบายเครื่องมือเปิดแบบข้ามต้นทาง
นโยบายเครื่องมือเปิดแบบข้ามต้นทาง (COOP) ช่วยให้คุณมั่นใจได้ว่ามีการแยกหน้าต่างระดับบนสุดออกจากเอกสารอื่นๆ ด้วยการนำหน้าต่างเหล่านั้นไปไว้ในกลุ่มบริบทการท่องเว็บที่แตกต่างกัน เพื่อไม่ให้หน้าต่างระดับบนสุดโต้ตอบกับหน้าต่างระดับบนสุดโดยตรง เช่น หากเอกสารที่มี COOP เปิดป๊อปอัป พร็อพเพอร์ตี้ window.opener
ของหน้านั้นจะเป็น null
นอกจากนี้ พร็อพเพอร์ตี้ .closed
ของการอ้างอิงของเครื่องมือเปิดจะแสดง true
ส่วนหัว Cross-Origin-Opener-Policy
มีค่าที่เป็นไปได้ 3 ค่า ได้แก่
Cross-Origin-Opener-Policy: same-origin
เอกสารที่มีเครื่องหมาย same-origin
จะแชร์กลุ่มบริบทการท่องเว็บเดียวกันซึ่งมีเอกสารต้นทางเดียวกันที่ทำเครื่องหมายเป็น same-origin
อย่างชัดแจ้งได้เช่นกัน
Cross-Origin-Opener-Policy: same-origin-allow-popups
เอกสารระดับบนสุดที่มี same-origin-allow-popups
จะเก็บการอ้างอิงไปยังป๊อปอัปที่ไม่ได้ตั้งค่า COOP หรือเลือกไม่ใช้การแยกโดยตั้งค่า COOP เป็น unsafe-none
Cross-Origin-Opener-Policy: unsafe-none
unsafe-none
เป็นค่าเริ่มต้นและอนุญาตให้เพิ่มเอกสารลงในกลุ่มบริบทการเรียกดูของเครื่องมือเปิดได้ เว้นแต่ตัวเปิดจะมี COOP เป็น same-origin
สรุป
หากต้องการเข้าถึงฟีเจอร์ที่มีประสิทธิภาพอย่าง SharedArrayBuffer
, performance.measureUserAgentSpecificMemory()
หรือตัวจับเวลาความละเอียดสูงด้วยความแม่นยำมากขึ้น โปรดทราบว่าเอกสารต้องใช้ทั้ง COEP ที่มีค่า require-corp
และ COOP ที่มีค่า same-origin
หากไม่มีทั้ง 2 อย่างนี้ เบราว์เซอร์จะไม่รับประกันว่าจะแยกได้อย่างเพียงพอที่จะเปิดใช้ฟีเจอร์ที่มีประสิทธิภาพเหล่านั้นได้อย่างปลอดภัย คุณตรวจสอบสถานการณ์ของหน้าเว็บได้โดยตรวจสอบว่า self.crossOriginIsolated
แสดงผล true
หรือไม่
ดูขั้นตอนในการใช้งานได้ที่การทำให้เว็บไซต์ "แยกแบบข้ามต้นทาง" โดยใช้ COOP และ COEP