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

ดูสาเหตุที่จําเป็นต้องใช้การแยกแบบข้ามต้นทางเพื่อใช้ฟีเจอร์ที่มีประสิทธิภาพ เช่น 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) ฟีเจอร์นี้ช่วยให้คุณประกาศว่าเอกสารโหลดทรัพยากรดังกล่าวไม่ได้

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

หากต้องการเปิดใช้งานนโยบายนี้ ให้เพิ่มส่วนหัว 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

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

แหล่งข้อมูล