ทำไมจึงต้องใช้ "การแยกแบบข้ามต้นทาง" สำหรับฟีเจอร์ที่มีประสิทธิภาพ

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

บทนำ

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

ฉากหลัง

เว็บสร้างขึ้นจากนโยบายต้นทางเดียวกัน ซึ่งเป็นฟีเจอร์ความปลอดภัยที่จำกัดวิธีที่เอกสารและสคริปต์โต้ตอบกับทรัพยากรจากต้นทางอื่น หลักการนี้ จำกัดวิธีที่เว็บไซต์เข้าถึงทรัพยากรข้ามต้นทางได้ เช่น ระบบจะป้องกันไม่ให้เอกสารจาก https://a.example เข้าถึงข้อมูล ที่โฮสต์ใน https://b.example

อย่างไรก็ตาม นโยบายต้นทางเดียวกันมีข้อยกเว้นในอดีตบางประการ เว็บไซต์ใดก็ได้ทำสิ่งต่อไปนี้

  • ฝัง iframe แบบข้ามต้นทาง
  • รวมทรัพยากรข้ามต้นทาง เช่น รูปภาพหรือสคริปต์
  • เปิดหน้าต่างป๊อปอัปข้ามต้นทางด้วยการอ้างอิง DOM

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

เราได้แก้ไขผลข้างเคียงด้านความปลอดภัยของนโยบายต้นทางเดียวกันที่หละหลวมดังกล่าวใน 2 วิธี วิธีหนึ่งคือการเปิดตัวโปรโตคอลใหม่ที่เรียกว่าการแชร์ทรัพยากรข้ามโดเมน (CORS) ซึ่งมีจุดประสงค์เพื่อให้มั่นใจว่าเซิร์ฟเวอร์อนุญาตให้แชร์ทรัพยากรกับต้นทางที่กำหนด อีกวิธีหนึ่งคือการนำสิทธิ์เข้าถึงสคริปต์โดยตรงไปยังทรัพยากรข้ามต้นทางออกโดยนัยในขณะที่ยังคงรักษาความเข้ากันได้แบบย้อนหลัง เราเรียกทรัพยากรข้ามต้นทางดังกล่าวว่าทรัพยากร "ทึบแสง" เช่น นี่คือเหตุผลที่การ จัดการพิกเซลของรูปภาพแบบข้ามโดเมนผ่าน CanvasRenderingContext2D จะล้มเหลว เว้นแต่จะใช้ CORS กับรูปภาพ

การตัดสินใจเกี่ยวกับนโยบายทั้งหมดนี้เกิดขึ้นภายในกลุ่มบริบทการเรียกดู

กลุ่มบริบทการท่องเว็บ

เป็นเวลานานแล้วที่การผสมผสานระหว่าง CORS และทรัพยากรที่ทึบแสงก็เพียงพอที่จะทำให้เบราว์เซอร์ปลอดภัย บางครั้งก็พบเคสข้อยกเว้น (เช่น ช่องโหว่ของ JSON) และจำเป็นต้องแก้ไข แต่โดยรวมแล้วหลักการที่ไม่อนุญาตให้มีสิทธิ์การอ่านโดยตรงไปยังไบต์ดิบของทรัพยากรข้ามต้นทางก็ประสบความสำเร็จ

แต่ทุกอย่างเปลี่ยนไปเมื่อมี Spectre ซึ่ง ทำให้ข้อมูลใดก็ตามที่โหลดไปยังกลุ่มบริบทการท่องเว็บเดียวกันกับโค้ดของคุณ อาจอ่านได้ การวัดเวลาที่การดำเนินการบางอย่างใช้จะช่วยให้ผู้โจมตี คาดเดาเนื้อหาของแคช CPU และเนื้อหาของหน่วยความจำ ของกระบวนการได้ การโจมตีตามเวลาดังกล่าวสามารถทำได้ด้วยตัวจับเวลาที่มีความละเอียดต่ำ ซึ่งมีอยู่ในแพลตฟอร์ม แต่สามารถเร่งให้เร็วขึ้นได้ด้วยตัวจับเวลาที่มีความละเอียดสูง ทั้งแบบชัดแจ้ง (เช่น performance.now()) และแบบโดยนัย (เช่น SharedArrayBuffers) หาก evil.com ฝังรูปภาพข้ามต้นทาง ผู้โจมตีจะใช้การโจมตี Spectre เพื่ออ่านข้อมูลพิกเซลของรูปภาพได้ ซึ่งจะทำให้การป้องกันที่อาศัย "ความทึบ" ไม่ได้ผล

Spectr

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

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

นโยบายเครื่องมือฝังแบบข้ามต้นทาง

นโยบายเครื่องมือฝังแบบข้ามต้นทาง (COEP) ป้องกันไม่ให้เอกสารโหลดทรัพยากรข้ามต้นทางใดๆ ที่ไม่ได้ให้สิทธิ์แก่เอกสารอย่างชัดเจน (โดยใช้ CORP หรือ CORS) ฟีเจอร์นี้ช่วยให้คุณประกาศได้ว่าเอกสารโหลดทรัพยากรดังกล่าวไม่ได้

วิธีการทำงานของ COEP

หากต้องการเปิดใช้งานนโยบายนี้ ให้ต่อท้ายส่วนหัว HTTP ต่อไปนี้ในเอกสาร

Cross-Origin-Embedder-Policy: require-corp

COEP ใช้ค่าเดียวคือ require-corp ซึ่งบังคับใช้นโยบายที่ว่าเอกสารจะโหลดได้เฉพาะทรัพยากรจากต้นทางเดียวกัน หรือทรัพยากรที่ทำเครื่องหมายอย่างชัดเจนว่าโหลดได้จากต้นทางอื่น

หากต้องการโหลดทรัพยากรจากต้นทางอื่น ทรัพยากรนั้นต้องรองรับ กลไกการแชร์ทรัพยากรข้ามโดเมน (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

COOP

ส่วนหัว Cross-Origin-Opener-Policy มีค่าที่เป็นไปได้ 3 ค่า ดังนี้

Cross-Origin-Opener-Policy: same-origin

เอกสารที่ทำเครื่องหมาย same-origin จะแชร์กลุ่มบริบทการท่องเว็บเดียวกันกับเอกสารที่มาจากต้นทางเดียวกันซึ่งทำเครื่องหมาย same-origin อย่างชัดเจนได้

COOP

Cross-Origin-Opener-Policy: same-origin-allow-popups

เอกสารระดับบนสุดที่มี same-origin-allow-popups จะเก็บการอ้างอิงถึงป๊อปอัปใดๆ ซึ่งไม่ได้ตั้งค่า COOP หรือเลือกไม่ใช้การแยกโดย ตั้งค่า COOP เป็น unsafe-none

COOP

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

แหล่งข้อมูล