เว็บแอปพลิเคชันจำนวนมากจำเป็นต้องแสดงเนื้อหาที่ผู้ใช้ควบคุม ซึ่งอาจทำได้ง่ายๆ เพียงแสดงรูปภาพที่ผู้ใช้อัปโหลด (เช่น รูปโปรไฟล์) หรือซับซ้อนอย่างเช่นการแสดงผล HTML ที่ผู้ใช้ควบคุม (เช่น บทแนะนำการพัฒนาเว็บ) การดำเนินการนี้ทำได้ยากเสมอมา เราจึงพยายามค้นหาโซลูชันที่ใช้งานง่ายแต่ปลอดภัยซึ่งนำไปใช้กับเว็บแอปพลิเคชันประเภทต่างๆ ได้
โซลูชันแบบคลาสสิกสำหรับการแยกเนื้อหาที่ไม่น่าเชื่อถือ
โซลูชันแบบคลาสสิกในการแสดงเนื้อหาที่ผู้ใช้ควบคุมอย่างปลอดภัยคือการใช้สิ่งที่เรียกว่าโดเมนแซนด์บ็อกซ์ แนวคิดพื้นฐานคือ หากโดเมนหลักของแอปพลิเคชันคือ example.com
คุณจะแสดงเนื้อหาที่ไม่น่าเชื่อถือทั้งหมดใน exampleusercontent.com
ได้ เนื่องจากโดเมน 2 โดเมนนี้เป็นโดเมนข้ามเว็บไซต์ เนื้อหาที่เป็นอันตรายใน exampleusercontent.com
จึงไม่สามารถส่งผลกระทบต่อ example.com
แนวทางนี้สามารถใช้เพื่อแสดงเนื้อหาที่ไม่น่าเชื่อถือทุกประเภทได้อย่างปลอดภัย ซึ่งรวมถึงรูปภาพ การดาวน์โหลด และ HTML แม้ว่าอาจดูเหมือนว่าไม่จำเป็นต้องใช้กับรูปภาพหรือการดาวน์โหลด แต่การดำเนินการดังกล่าวจะช่วยหลีกเลี่ยงความเสี่ยงจากการสแกนเนื้อหา โดยเฉพาะในเบราว์เซอร์รุ่นเดิม
โดเมนแซนด์บ็อกซ์มีการใช้งานอย่างแพร่หลายในอุตสาหกรรมและใช้งานได้ดีมาเป็นเวลานาน แต่ก็มีข้อเสียที่สำคัญ 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'
เพื่อบล็อกไม่ให้ฝังปลายทาง - เนื้อหาของผู้ใช้ใน Sandbox ในโดเมนย่อยที่แยกต่างหากโดยทำดังนี้
- การแสดงเนื้อหาของผู้ใช้ในโดเมนย่อยที่แยกต่างหาก (เช่น 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
ทั้งหมดจะส่งไปยังไฟล์ชิมแบบคงที่ ไฟล์ชิมนี้มีข้อมูลโค้ด HTML และ JavaScript สั้นๆ ที่คอยฟังเหตุการณ์message
และแสดงผลเนื้อหาที่ได้รับ - หากต้องการใช้ฟีเจอร์นี้ ผลิตภัณฑ์จะสร้าง iframe หรือป๊อปอัปไปยัง
$RANDOM_VALUE.exampleusercontent.com/shim
และใช้postMessage
เพื่อส่งเนื้อหาที่ไม่น่าเชื่อถือไปยังชิมเพื่อแสดงผล - ระบบจะเปลี่ยนรูปแบบเนื้อหาที่แสดงผลเป็น Blob และแสดงผลภายใน iframe ที่ทำแซนด์บ็อกซ์
เมื่อเทียบกับแนวทางโดเมนแซนด์บ็อกซ์แบบคลาสสิก วิธีนี้ช่วยให้มั่นใจได้ว่าเนื้อหาทั้งหมดจะแยกอยู่ในเว็บไซต์ที่ไม่ซ้ำกันโดยสมบูรณ์ และเมื่อมีแอปพลิเคชันหลักจัดการกับการดึงข้อมูลที่จะแสดงผล คุณก็ไม่จําเป็นต้องใช้ URL ความสามารถอีกต่อไป
บทสรุป
โซลูชันทั้ง 2 รายการนี้ช่วยให้คุณย้ายข้อมูลจากโดเมนแซนด์บ็อกซ์แบบคลาสสิก เช่น googleusercontent.com
ไปยังโซลูชันที่ปลอดภัยกว่าซึ่งเข้ากันได้กับการบล็อกคุกกี้ของบุคคลที่สาม เราที่ Google ได้ย้ายข้อมูลผลิตภัณฑ์หลายรายการไปใช้โซลูชันเหล่านี้แล้ว และวางแผนที่จะย้ายข้อมูลเพิ่มเติมในปีหน้า