การโฮสต์ข้อมูลผู้ใช้อย่างปลอดภัยในเว็บแอปพลิเคชันสมัยใหม่

David Dworken
David Dworken

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

วิธีที่ 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 เราได้ย้ายข้อมูลผลิตภัณฑ์จำนวนมากเพื่อใช้โซลูชันเหล่านี้แล้ว และวางแผนที่จะย้ายข้อมูลอื่นๆ เพิ่มเติมในปีหน้า