เว็บแอปพลิเคชันจำนวนมากจำเป็นต้องแสดงเนื้อหาที่ผู้ใช้ควบคุม ซึ่งอาจง่ายอย่างการแสดงรูปภาพที่ผู้ใช้อัปโหลด (เช่น รูปโปรไฟล์) หรือซับซ้อนพอๆ กับการแสดงผล HTML ที่ผู้ใช้ควบคุม (ตัวอย่างเช่น บทแนะนำการพัฒนาเว็บ) การดำเนินการอย่างปลอดภัยนั้นเป็นเรื่องยากเสมอ ดังนั้นเราจึงได้พยายามค้นหาโซลูชันที่ง่ายและปลอดภัย ซึ่งสามารถใช้ได้กับเว็บแอปพลิเคชันเกือบทุกประเภท
โซลูชันแบบคลาสสิกสำหรับการแยกเนื้อหาที่ไม่น่าเชื่อถือ
โซลูชันแบบคลาสสิกสำหรับการแสดงเนื้อหาที่ควบคุมโดยผู้ใช้อย่างปลอดภัยคือการใช้สิ่งที่เรียกว่าโดเมนแซนด์บ็อกซ์ แนวคิดพื้นฐานคือหากโดเมนหลักของแอปพลิเคชันคือ example.com
คุณสามารถแสดงเนื้อหาที่ไม่น่าไว้วางใจทั้งหมดใน exampleusercontent.com
เนื่องจาก 2 โดเมนนี้เป็นแบบข้ามเว็บไซต์ เนื้อหาที่เป็นอันตรายใน exampleusercontent.com
จึงไม่ส่งผลกระทบต่อ example.com
คุณสามารถใช้วิธีนี้เพื่อแสดงเนื้อหาที่ไม่น่าเชื่อถือทุกประเภทได้อย่างปลอดภัย รวมถึงรูปภาพ การดาวน์โหลด และ HTML แม้ว่าอาจดูเหมือนไม่จำเป็นต้องใช้สิ่งนี้สำหรับรูปภาพหรือการดาวน์โหลด แต่การดำเนินการดังกล่าวจะช่วยลดความเสี่ยงจากการดักจับเนื้อหา โดยเฉพาะในเบราว์เซอร์รุ่นเก่า
โดเมน Sandbox มีการใช้งานอย่างแพร่หลายในอุตสาหกรรมและมีการใช้งานมานานแล้ว แต่ก็มีข้อเสียหลักๆ 2 ด้าน ดังนี้
- แอปพลิเคชันมักต้องจำกัดการเข้าถึงเนื้อหาสำหรับผู้ใช้รายเดียว ซึ่งจำเป็นต้องมีการตรวจสอบสิทธิ์และการให้สิทธิ์ เนื่องจากโดเมนแซนด์บ็อกซ์จงใจไม่แชร์คุกกี้กับโดเมนแอปพลิเคชันหลัก สิ่งนี้จึงยากมากที่จะทำอย่างปลอดภัย หากต้องการรองรับการตรวจสอบสิทธิ์ เว็บไซต์อาจต้องใช้ URL ความสามารถ หรือต้องตั้งค่าคุกกี้การตรวจสอบสิทธิ์แยกต่างหากสำหรับโดเมนแซนด์บ็อกซ์ วิธีที่สองนี้เป็นปัญหาโดยเฉพาะอย่างยิ่งในเว็บสมัยใหม่ที่เบราว์เซอร์จำนวนมากจำกัดคุกกี้ข้ามเว็บไซต์โดยค่าเริ่มต้น
- แม้ว่าเนื้อหาของผู้ใช้จะแยกออกมาจากเว็บไซต์หลัก แต่ไม่ได้แยกออกจากเนื้อหาอื่นๆ ของผู้ใช้ ซึ่งเป็นการสร้างความเสี่ยงที่เนื้อหาที่เป็นอันตรายของผู้ใช้จะโจมตีข้อมูลอื่นๆ ในโดเมนแซนด์บ็อกซ์ (เช่น ผ่านการอ่านข้อมูลต้นทางเดียวกัน)
นอกจากนี้ โดเมนแซนด์บ็อกซ์จะช่วยลดความเสี่ยงในการฟิชชิง เนื่องจากมีการแบ่งทรัพยากรออกเป็นส่วนๆ อย่างชัดเจนในโดเมนที่แยกต่างหาก
โซลูชันสมัยใหม่สำหรับการแสดงเนื้อหาให้ผู้ใช้
เมื่อเวลาผ่านไป เว็บมีการพัฒนา และในปัจจุบันมีวิธีแสดงเนื้อหาที่ไม่น่าไว้วางใจได้ง่ายและปลอดภัยยิ่งขึ้น ซึ่งในที่นี้มีหลายวิธีด้วยกัน ดังนั้นเราจะกล่าวถึงโซลูชัน 2 อย่างที่ใช้กันอย่างแพร่หลายที่ Google ในปัจจุบัน
วิธีที่ 1: การแสดงเนื้อหาของผู้ใช้ที่ไม่ได้ใช้งาน
หากเว็บไซต์เพียงแต่แสดงเนื้อหาของผู้ใช้ที่ไม่ได้ใช้งาน (เนื้อหาที่ไม่ใช่ HTML หรือ JavaScript เช่น รูปภาพและการดาวน์โหลด) ก็สามารถดําเนินการนี้ได้อย่างปลอดภัยโดยไม่ต้องมีโดเมนแซนด์บ็อกซ์แยกต่างหาก มีขั้นตอนสำคัญ 2 ขั้นตอนดังนี้
- ตั้งค่าส่วนหัว
Content-Type
เป็นประเภท MIME ที่รู้จักกันดีซึ่งเบราว์เซอร์ทั้งหมดรองรับ และรับประกันว่าจะไม่มีเนื้อหาที่ใช้งานอยู่ (หากไม่แน่ใจ ให้ใช้application/octet-stream
เป็นตัวเลือกที่ปลอดภัย) - นอกจากนี้ ให้ตั้งค่าส่วนหัวการตอบกลับด้านล่างเสมอเพื่อให้เบราว์เซอร์แยกการตอบกลับออกมาทั้งหมด
ส่วนหัวการตอบกลับ | Purpose |
---|---|
X-Content-Type-Options: nosniff |
ป้องกันการดักจับเนื้อหา |
Content-Disposition: attachment; filename="download" |
ทริกเกอร์การดาวน์โหลดแทนการแสดงผล |
Content-Security-Policy: sandbox |
แซนด์บ็อกซ์เนื้อหาให้เหมือนกับว่าเนื้อหาแสดงบนโดเมนแยกต่างหาก |
Content-Security-Policy: default-src ‘none' |
ปิดใช้การเรียกใช้ JavaScript (และการรวมทรัพยากรย่อยทั้งหมด) |
Cross-Origin-Resource-Policy: same-site |
ป้องกันไม่ให้รวมหน้าแบบข้ามเว็บไซต์ |
การใช้ส่วนหัวร่วมกันนี้ช่วยให้มั่นใจว่าการตอบกลับจะโหลดเป็นทรัพยากรย่อยในแอปพลิเคชันของคุณเท่านั้น หรือดาวน์โหลดเป็นไฟล์ได้โดยผู้ใช้ นอกจากนี้ ส่วนหัวยังให้การป้องกันข้อบกพร่องของเบราว์เซอร์แบบหลายชั้นผ่านส่วนหัวของแซนด์บ็อกซ์ CSP และข้อจำกัดของ default-src
โดยรวมแล้ว การตั้งค่าที่อธิบายไว้ข้างต้นให้ความมั่นใจในระดับสูงว่าการตอบสนองที่แสดงในลักษณะนี้จะไม่ทำให้เกิดช่องโหว่ในการแทรกหรือแยกแอป
การป้องกันเชิงลึก
แม้ว่าโดยทั่วไปแล้ว วิธีแก้ปัญหาข้างต้นจะแสดงให้เห็นถึงการป้องกัน XSS ที่เพียงพอ แต่ก็มีมาตรการเสริมอีกหลายวิธีที่คุณสามารถใช้เพื่อเพิ่มระดับความปลอดภัยได้ ดังนี้
- ตั้งค่าส่วนหัว
X-Content-Security-Policy: sandbox
เพื่อให้เข้ากันได้กับ IE11 - ตั้งค่าส่วนหัว
Content-Security-Policy: frame-ancestors 'none'
เพื่อบล็อกไม่ให้ฝังปลายทาง - เนื้อหาของผู้ใช้แซนด์บ็อกซ์ในโดเมนย่อยที่แยกต่างหากโดย:
- การแสดงเนื้อหาของผู้ใช้ในโดเมนย่อยที่แยกต่างหาก (เช่น Google ใช้โดเมนต่างๆ เช่น
product.usercontent.google.com
) - ตั้งค่า
Cross-Origin-Opener-Policy: same-origin
และCross-Origin-Embedder-Policy: require-corp
เพื่อเปิดใช้การแยกแบบข้ามต้นทาง
- การแสดงเนื้อหาของผู้ใช้ในโดเมนย่อยที่แยกต่างหาก (เช่น Google ใช้โดเมนต่างๆ เช่น
วิธีที่ 2: การแสดงเนื้อหาของผู้ใช้ที่ใช้งานอยู่
การแสดงเนื้อหาที่ใช้งานอยู่ (เช่น รูปภาพ HTML หรือ SVG) อย่างปลอดภัยก็สามารถทำได้โดยไม่มีจุดอ่อนของแนวทางการใช้โดเมนแซนด์บ็อกซ์แบบคลาสสิก
ตัวเลือกที่ง่ายที่สุดคือการใช้ประโยชน์จากส่วนหัว Content-Security-Policy: sandbox
เพื่อบอกให้เบราว์เซอร์แยกการตอบกลับออกมา แม้ว่าขณะนี้บางเว็บเบราว์เซอร์จะใช้การแยกกระบวนการสำหรับเอกสารแซนด์บ็อกซ์ แต่การปรับแต่งโมเดลการประมวลผลของเบราว์เซอร์อย่างต่อเนื่องมีแนวโน้มที่จะปรับปรุงการแยกเนื้อหาแซนด์บ็อกซ์ออกจากแอปพลิเคชันที่ฝัง หากการโจมตีของ SpectreJS และการบุกรุกผู้แสดงผลอยู่นอกโมเดลภัยคุกคาม การใช้แซนด์บ็อกซ์ CSP ก็น่าจะเป็นโซลูชันที่เหมาะสม
Google พัฒนาโซลูชันที่สามารถแยกเนื้อหาที่ใช้งานอยู่ซึ่งไม่น่าเชื่อถือโดยสิ้นเชิงได้ด้วยการปรับแนวคิดของโดเมนแซนด์บ็อกซ์ให้ทันสมัย แนวคิดหลักก็คือการ
- สร้างโดเมนแซนด์บ็อกซ์ใหม่ที่เพิ่มลงในรายการคำต่อท้ายสาธารณะ ตัวอย่างเช่น การเพิ่ม
exampleusercontent.com
ลงใน PSL จะทำให้มั่นใจได้ว่าfoo.exampleusercontent.com
และbar.exampleusercontent.com
เป็นแบบข้ามเว็บไซต์และแยกกันโดยสิ้นเชิง - ระบบจะกำหนดเส้นทาง URL ที่ตรงกับ
*.exampleusercontent.com/shim
ทั้งหมดไปยังไฟล์ Shim แบบคงที่ ไฟล์ shim นี้มีข้อมูลโค้ด HTML และ JavaScript สั้นๆ ที่คอยฟังเครื่องจัดการเหตุการณ์message
และแสดงผลเนื้อหาทั้งหมดที่ได้รับ - หากต้องการใช้ฟีเจอร์นี้ ผลิตภัณฑ์จะสร้าง iframe หรือป๊อปอัปไปยัง
$RANDOM_VALUE.exampleusercontent.com/shim
และใช้postMessage
เพื่อส่งเนื้อหาที่ไม่น่าเชื่อถือไปยัง Shim เพื่อการแสดงผล - เนื้อหาที่แสดงผลจะเปลี่ยนรูปแบบเป็น Blob และแสดงผลภายใน iframe ที่ทำแซนด์บ็อกซ์
เมื่อเทียบกับแนวทางการใช้โดเมนแซนด์บ็อกซ์แบบคลาสสิก วิธีนี้ทำให้มั่นใจได้ว่าเนื้อหาทั้งหมดจะถูกแยกออกจากไซต์ที่ไม่ซ้ำกันโดยสมบูรณ์ และการให้แอปพลิเคชันหลักทำหน้าที่ในการเรียกข้อมูลเพื่อแสดงผล ก็ไม่จำเป็นต้องใช้ URL ความสามารถอีกต่อไป
บทสรุป
เมื่อใช้ร่วมกัน โซลูชัน 2 รายการนี้จะช่วยให้สามารถย้ายข้อมูลออกจากโดเมนแซนด์บ็อกซ์แบบคลาสสิก เช่น googleusercontent.com
ไปยังโซลูชันที่ปลอดภัยกว่าซึ่งเข้ากันได้กับการบล็อกคุกกี้ของบุคคลที่สาม ที่ Google เราได้ย้ายข้อมูลผลิตภัณฑ์จำนวนมากเพื่อใช้โซลูชันเหล่านี้แล้ว และวางแผนที่จะย้ายข้อมูลอื่นๆ เพิ่มเติมในปีหน้า