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

ดูเหตุผลที่ต้องใช้การแยกแบบข้ามต้นทางเพื่อใช้ฟีเจอร์ที่มีประสิทธิภาพ เช่น 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()) และแบบไม่ชัดเจน (เช่น SharedArrayBuffer) หาก 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 ของ opener จะแสดงผลเป็น 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 หากไม่มีสิ่งใดสิ่งหนึ่ง เบราว์เซอร์จะไม่รับประกันการแยกที่เพียงพอเพื่อเปิดใช้ฟีเจอร์ที่มีประสิทธิภาพเหล่านั้นอย่างปลอดภัย คุณสามารถระบุสถานการณ์ของหน้าเว็บได้โดยดูว่า self.crossOriginIsolated แสดงผลเป็น true หรือไม่

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

แหล่งข้อมูล