การอัปเดต SharedArrayBuffer ใน Android Chrome 88 และ Chrome 92 ในเดสก์ท็อป

SharedArrayBuffer อาจมีช่วงที่ใช้งานบนเว็บได้ไม่ราบรื่นนัก แต่ตอนนี้ทุกอย่างก็เริ่มเข้าที่เข้าทางแล้ว สิ่งที่จำเป็นต้องทราบมีดังนี้

โดยย่อ

  • ขณะนี้ Firefox 79 ขึ้นไปรองรับ SharedArrayBuffer และจะพร้อมใช้งานใน Android Chrome 88 อย่างไรก็ตาม ฟีเจอร์นี้ใช้ได้เฉพาะกับหน้าที่แยกแบบข้ามต้นทาง
  • ปัจจุบัน SharedArrayBuffer พร้อมใช้งานใน Chrome บนเดสก์ท็อป แต่ตั้งแต่ Chrome 92 เป็นต้นไป จะจำกัดเฉพาะหน้าเว็บที่แยกแบบข้ามต้นทาง หากคุณคิดว่าไม่สามารถทำการเปลี่ยนแปลงนี้ได้ทันเวลา คุณสามารถลงทะเบียนเพื่อทดลองใช้ต้นทางเพื่อรักษาลักษณะการทำงานปัจจุบันไว้จนถึง Chrome 113 เป็นอย่างน้อย
  • หากคุณตั้งใจที่จะเปิดใช้การแยกต้นทางข้ามเพื่อใช้ SharedArrayBufferต่อไป ให้ประเมินผลกระทบที่จะเกิดขึ้นกับองค์ประกอบอื่นๆ ที่มีต้นทางข้าม ในเว็บไซต์ เช่น ตําแหน่งโฆษณา ตรวจสอบว่าแหล่งข้อมูลของบุคคลที่สามใช้ SharedArrayBuffer เพื่อทำความเข้าใจผลกระทบและ คำแนะนำหรือไม่

ภาพรวมการแยกแบบข้ามต้นทาง

คุณทำให้หน้าเว็บแยกแบบข้ามต้นทางได้โดยแสดงหน้าเว็บด้วยส่วนหัวต่อไปนี้

Cross-Origin-Embedder-Policy: require-corp
Cross-Origin-Opener-Policy: same-origin

เมื่อดำเนินการนี้แล้ว หน้าเว็บจะโหลดเนื้อหาแบบข้ามโดเมนไม่ได้ เว้นแต่ว่า ทรัพยากรจะอนุญาตอย่างชัดเจนผ่านส่วนหัว Cross-Origin-Resource-Policy หรือส่วนหัว CORS (Access-Control-Allow-* และอื่นๆ)

นอกจากนี้ยังมี API การรายงานเพื่อให้คุณรวบรวมข้อมูลเกี่ยวกับคำขอที่ล้มเหลวอันเป็นผลมาจาก Cross-Origin-Embedder-Policy และ Cross-Origin-Opener-Policy ได้

หากคิดว่าคุณไม่สามารถทำการเปลี่ยนแปลงเหล่านี้ได้ทันเวลาสำหรับ Chrome 92 คุณสามารถลงทะเบียนเพื่อทดลองใช้ Origin เพื่อคงลักษณะการทำงานของ Chrome บนเดสก์ท็อปในปัจจุบันไว้จนถึง Chrome 113 เป็นอย่างน้อย

ดูคำแนะนำและข้อมูลเพิ่มเติมเกี่ยวกับการแยกต้นทางแบบข้ามได้ที่ส่วนอ่านเพิ่มเติมที่ด้านล่างของหน้านี้

เรามาถึงจุดนี้ได้อย่างไร

SharedArrayBuffer เปิดตัวใน Chrome 60 (เดือนกรกฎาคม 2017 สำหรับผู้ที่ คิดถึงเวลาในรูปแบบวันที่แทนที่จะเป็นเวอร์ชัน Chrome) และทุกอย่างก็เป็นไปด้วยดี เป็นเวลา 6 เดือน

ในเดือนมกราคม 2018 มีการเปิดเผยช่องโหว่ใน CPU ยอดนิยมบางรุ่น ดูรายละเอียดทั้งหมดได้ในประกาศ แต่โดยพื้นฐานแล้วหมายความว่าโค้ดสามารถใช้ตัวจับเวลาที่มีความละเอียดสูง เพื่ออ่านหน่วยความจำที่โค้ดไม่ควรมีสิทธิ์เข้าถึง

ซึ่งเป็นปัญหาสำหรับผู้ให้บริการเบราว์เซอร์อย่างเรา เนื่องจากเราต้องการอนุญาตให้เว็บไซต์เรียกใช้โค้ดในรูปแบบของ JavaScript และ WASM แต่ควบคุมหน่วยความจำที่โค้ดนี้เข้าถึงได้อย่างเข้มงวด หากคุณเข้าชมเว็บไซต์ของฉัน ฉันไม่ควรจะอ่านข้อมูลใดๆ จากเว็บไซต์ธนาคารออนไลน์ที่คุณเปิดอยู่ได้ จริงๆ แล้วฉันไม่ควร รู้ด้วยซ้ำว่าคุณเปิดเว็บไซต์ธนาคารทางอินเทอร์เน็ตอยู่ ซึ่งเป็นพื้นฐานของ ความปลอดภัยบนเว็บ

เราจึงลดความละเอียดของตัวจับเวลาความละเอียดสูง เช่น performance.now() เพื่อลดผลกระทบนี้ อย่างไรก็ตาม คุณสร้างตัวจับเวลาที่มีความละเอียดสูงได้โดยใช้ SharedArrayBuffer ด้วยการแก้ไขหน่วยความจำในลูปที่แน่นใน Worker และอ่าน กลับในอีกเธรดหนึ่ง ซึ่งไม่สามารถลดผลกระทบได้อย่างมีประสิทธิภาพโดยไม่ส่งผลกระทบอย่างมากต่อโค้ดที่ตั้งใจดี จึงต้องปิดใช้ SharedArrayBuffer ทั้งหมด

การลดความเสี่ยงโดยทั่วไปคือการตรวจสอบว่ากระบวนการของระบบในหน้าเว็บไม่มีข้อมูลที่ละเอียดอ่อนจากที่อื่น Chrome ได้ลงทุนในสถาปัตยกรรมแบบหลายกระบวนการ ตั้งแต่เริ่มต้น (จำการ์ตูนได้ไหม) แต่ก็ยังคงมีกรณีที่ข้อมูลจากหลายเว็บไซต์อาจอยู่ในกระบวนการเดียวกัน

<iframe src="https://your-bank.example/balance.json"></iframe>
<script src="https://your-bank.example/balance.json"></script>
<link rel="stylesheet" href="https://your-bank.example/balance.json" />
<img src="https://your-bank.example/balance.json" />
<video src="https://your-bank.example/balance.json"></video>
<!-- …and more… -->

API เหล่านี้มีลักษณะการทำงานแบบ "เดิม" ซึ่งอนุญาตให้ใช้เนื้อหาจากต้นทางอื่นๆ ได้โดยไม่ต้องเลือกใช้จากต้นทางอื่น คำขอเหล่านี้สร้างขึ้นโดยใช้คุกกี้ของต้นทางอื่น จึงเป็นคำขอ "เข้าสู่ระบบ" แบบเต็ม ปัจจุบัน API ใหม่ๆ กำหนดให้ต้นทางอื่นเลือกใช้โดยใช้ CORS

เราได้แก้ไข API เดิมเหล่านี้ด้วยการป้องกันไม่ให้เนื้อหาเข้าสู่กระบวนการของหน้าเว็บหากดู "ไม่ถูกต้อง" และเรียกกระบวนการนี้ว่าการบล็อกการอ่านข้ามต้นทาง ดังนั้น ในกรณีข้างต้น เราจะไม่อนุญาตให้ JSON เข้าสู่กระบวนการ เนื่องจากไม่ใช่รูปแบบที่ถูกต้องสำหรับ API เหล่านั้น ยกเว้น iframe สำหรับ iframe เรา จะใส่เนื้อหาในกระบวนการอื่น

เมื่อมีมาตรการบรรเทาผลกระทบเหล่านี้แล้ว เราจึงได้นำ SharedArrayBuffer กลับมาใช้ใน Chrome 68 (กรกฎาคม 2018) แต่ใช้ได้บนเดสก์ท็อปเท่านั้น ข้อกำหนดของกระบวนการเพิ่มเติมทำให้เราไม่สามารถทำเช่นเดียวกันในอุปกรณ์เคลื่อนที่ได้ นอกจากนี้ ยังมีการระบุว่าโซลูชันของ Chrome ยังไม่สมบูรณ์ เนื่องจากเราบล็อกเฉพาะรูปแบบข้อมูลที่ "ไม่ถูกต้อง" เท่านั้น ในขณะที่ เป็นไปได้ (แม้ว่าจะไม่ปกติ) ที่ CSS/JS/รูปภาพที่ถูกต้องใน URL ที่คาดเดาได้อาจมีข้อมูลส่วนตัว

ผู้เชี่ยวชาญด้านมาตรฐานเว็บได้มารวมตัวกันเพื่อคิดค้นโซลูชันข้ามเบราว์เซอร์ที่สมบูรณ์ยิ่งขึ้น โซลูชันคือการให้หน้าเว็บมีวิธีระบุว่า "ข้าพเจ้าขอสละสิทธิ์ ในการนำเนื้อหาจากต้นทางอื่นมายังกระบวนการนี้โดยไม่ต้องขอรับความยินยอม" การประกาศนี้ทำผ่านส่วนหัว COOP และ COEP ที่แสดงพร้อมกับหน้าเว็บ เบราว์เซอร์จะบังคับใช้ข้อกำหนดดังกล่าว และในทางกลับกัน หน้าเว็บจะได้รับสิทธิ์เข้าถึง SharedArrayBuffer และ API อื่นๆ ที่มีสิทธิ์คล้ายกัน แหล่งที่มาอื่นๆ สามารถเลือกใช้การฝังเนื้อหาผ่าน Cross-Origin-Resource-Policy หรือ CORS

Firefox เป็นเบราว์เซอร์แรกที่เปิดตัว SharedArrayBuffer พร้อมข้อจำกัดนี้ใน เวอร์ชัน 79 (กรกฎาคม 2020)

จากนั้นในเดือนมกราคม 2021 ฉันได้เขียนบทความนี้ และคุณก็อ่านบทความนี้ สวัสดี

และนั่นคือจุดที่เราอยู่ตอนนี้ Chrome 88 จะนำ SharedArrayBuffer กลับมาใช้ใน Android สำหรับหน้าเว็บที่แยกแบบข้ามต้นทาง และ Chrome 92 จะนำข้อกำหนดเดียวกันนี้มาใช้กับเดสก์ท็อป ทั้งนี้เพื่อความสอดคล้องและเพื่อให้บรรลุการแยกแบบข้ามต้นทางทั้งหมด

การเลื่อนการเปลี่ยนแปลง Chrome บนเดสก์ท็อป

นี่เป็นข้อยกเว้นชั่วคราวในรูปแบบของ "Origin Trial" ที่ให้เวลาผู้ใช้มากขึ้นในการติดตั้งใช้งานหน้าแบบ cross-origin-isolated ซึ่งจะเปิดใช้ SharedArrayBuffer โดยไม่ต้องให้หน้าเว็บแยกแบบข้ามต้นทาง ข้อยกเว้นจะหมดอายุใน Chrome 113 และข้อยกเว้นจะมีผลกับ Chrome บนเดสก์ท็อปเท่านั้น

  1. ขอโทเค็นสำหรับต้นทาง
  2. เพิ่มโทเค็นลงในหน้าเว็บ ซึ่งทำได้ 2 วิธีดังนี้
    • เพิ่มแท็ก origin-trial <meta> ลงในส่วนหัวของแต่ละหน้า ตัวอย่างเช่น อาจมีลักษณะดังนี้
      <meta http-equiv="origin-trial" content="TOKEN_GOES_HERE">
    • หากกำหนดค่าเซิร์ฟเวอร์ได้ คุณยังเพิ่มโทเค็นได้โดยใช้ส่วนหัว HTTP ของ Origin-Trial ส่วนหัวการตอบกลับที่ได้ควรมีลักษณะดังนี้
      Origin-Trial: TOKEN_GOES_HERE

อ่านเพิ่มเติม

รูปภาพแบนเนอร์โดย Daniel Gregoire ใน Unsplash