เมื่อการสื่อสารระหว่างเว็บเพจกลายเป็นดาบสองคม: ไขความลับช่องโหว่ `postMessage`

เมื่อการสื่อสารระหว่างเว็บเพจกลายเป็นดาบสองคม: ไขความลับช่องโหว่ postMessage

โลกออนไลน์เต็มไปด้วยการเชื่อมโยง เว็บไซต์ต่างๆ ไม่ได้อยู่โดดเดี่ยวอีกต่อไป หลายครั้งที่เว็บไซต์จำเป็นต้องสื่อสารข้อมูลกัน เช่น การฝังวิดเจ็ตชำระเงิน หรือการแสดงเนื้อหาจากโดเมนอื่น

เบื้องหลังการทำงานเหล่านี้ มีกลไกสำคัญที่เรียกว่า postMessage ซึ่งทำหน้าที่เป็นสะพานเชื่อมให้เว็บเพจที่มาจากคนละโดเมน สามารถส่งข้อมูลถึงกันได้อย่างปลอดภัย ทว่า หากสะพานนี้ไม่ได้รับการตรวจสอบอย่างรัดกุม ก็อาจกลายเป็นช่องทางให้ผู้ไม่หวังดีใช้โจมตีได้

กลไก postMessage ทำงานอย่างไร

ลองนึกภาพว่าคุณมีหน้าเว็บหลัก และมีหน้าเว็บย่อยที่ถูกฝังอยู่ในรูปแบบของ iframe ซึ่งอาจมาจากโดเมนอื่น

postMessage ช่วยให้หน้าเว็บหลักส่งข้อความไปหา iframe ได้ และในทางกลับกัน iframe ก็สามารถส่งข้อความกลับมาหาหน้าเว็บหลักได้เช่นกัน

ในการส่งข้อความ ผู้ส่งจะต้องระบุ targetOrigin เพื่อบอกว่าข้อความนี้มีจุดประสงค์จะส่งไปหาโดเมนใด หากระบุเป็น * หมายถึงส่งไปหาทุกโดเมน ซึ่งมีความเสี่ยงสูง

เมื่อผู้รับได้รับข้อความ จะมีข้อมูลสำคัญที่เรียกว่า event.origin ติดมาด้วย ข้อมูลนี้บ่งบอกว่าข้อความที่ได้รับมาจากโดเมนไหน และนี่คือจุดที่สำคัญที่สุดในการป้องกันภัยคุกคาม

ช่องโหว่ที่แฝงมากับการตรวจสอบที่หละหลวม

ปัญหาเกิดขึ้นเมื่อเว็บเพจผู้รับไม่ได้ตรวจสอบ event.origin อย่างละเอียด หรือตรวจสอบผิดพลาด เช่น ไปเชื่อใจ event.origin ที่ถูกส่งมาโดยไม่ได้ตรวจสอบว่าเป็นโดเมนที่คาดหวังจริง ๆ

ผู้โจมตีสามารถอาศัยลูกเล่นที่เรียกว่า Data URI Redirects เพื่อสร้างหน้าเว็บปลอมที่ดูเหมือนว่าข้อความที่ส่งมานั้นมี event.origin มาจากโดเมนที่น่าเชื่อถือ ตัวอย่างเช่น การสร้าง iframe ที่ใช้ data:text/html,<script>window.location='trusted.com/evil'</script> จากนั้นภายใน trusted.com/evil ก็ส่ง postMessage กลับไปยังเว็บหลัก

แม้ว่าเบื้องต้นเว็บหลักจะเห็น event.origin เป็น trusted.com ซึ่งดูเหมือนปลอดภัย แต่ความจริงแล้วข้อความนั้นถูกส่งมาจากหน้าเว็บที่ผู้โจมตีควบคุมอยู่ นี่คือหัวใจสำคัญของการบายพาสการตรวจสอบต้นทาง

ผลกระทบร้ายแรง: การเข้ายึดบัญชี (Account Takeover)

เมื่อผู้โจมตีสามารถปลอมแปลง event.origin ได้สำเร็จ และเว็บเพจผู้รับประมวลผลข้อความเหล่านั้นโดยไม่ระมัดระวัง ผลลัพธ์ที่ตามมาอาจร้ายแรงกว่าที่คิด

ลองนึกภาพว่าคุณกำลังเข้าสู่ระบบธนาคารออนไลน์ หรือแพลตฟอร์มอีคอมเมิร์ซสำคัญ หากมีช่องโหว่ postMessage ในหน้าชำระเงิน หรือหน้าจัดการโปรไฟล์

ผู้โจมตีสามารถส่งข้อความที่ “ดูเหมือน” มาจากวิดเจ็ตที่เชื่อถือได้ โดยมีคำสั่งให้เปลี่ยนอีเมลที่ใช้ในการล็อกอิน เปลี่ยนรหัสผ่าน หรือแม้แต่เปลี่ยนรายละเอียดการชำระเงิน ผู้ใช้งานไม่ทันระวังก็อาจถูกเข้ายึดบัญชี (Account Takeover) ได้อย่างง่ายดาย ข้อมูลส่วนตัวและทรัพย์สินก็ตกอยู่ในอันตราย

ป้องกันอย่างไรไม่ให้ตกเป็นเหยื่อ

การป้องกันช่องโหว่ postMessage ต้องทำอย่างเคร่งครัดที่ฝั่งนักพัฒนาเว็บเพจผู้รับ

สิ่งสำคัญที่สุดคือ การตรวจสอบ event.origin อย่างละเอียด ทุกครั้งที่ได้รับข้อความผ่าน postMessage

ต้องแน่ใจว่า event.origin ตรงกับโดเมนที่คุณคาดหวังไว้เป๊ะๆ ห้ามใช้ * เป็น targetOrigin ในการส่งข้อความหากไม่จำเป็นจริง ๆ และห้ามใช้ * ในการตรวจสอบ event.origin ในฝั่งผู้รับ

กำหนดรายชื่อโดเมนที่เชื่อถือได้ (Whitelisted Domains) และตรวจสอบว่า event.origin อยู่ในรายชื่อนั้นเสมอ การเขียนโค้ดที่รัดกุมและตระหนักถึงภัยคุกคามลักษณะนี้เป็นสิ่งจำเป็น เพื่อสร้างประสบการณ์ใช้งานที่ปลอดภัยให้กับผู้ใช้งานทุกคนบนโลกออนไลน์