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

นำวิธีนี้ไปใช้กับเอกสารทั้งหมดซ้ำๆ รวมถึงเอกสารระดับบนสุด, iframe และสคริปต์ผู้ปฏิบัติงาน ดูข้อมูลเกี่ยวกับส่วนหัว 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 DevTools

คุณยังตรวจสอบสถานะของหน้าต่างป๊อปอัปได้ด้วย เช่น แยกกันหรือไม่สำหรับต้นทางต่างๆ

ตัวตรวจสอบหน้าต่างป๊อปอัปของ Chrome DevTools

ตรวจสอบปัญหาโดยใช้ 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 เพื่อดูว่าหน้าเว็บอยู่ในสถานะแยกกันข้ามแหล่งที่มาหรือไม่

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

แหล่งข้อมูล