
เมื่อ JavaScript กลายเป็นช่องโหว่: เจาะลึก DOM XSS
การโจมตีทางไซเบอร์มีหลากหลายรูปแบบ และหนึ่งในภัยคุกคามที่พบบ่อยบนเว็บไซต์คือ Cross-Site Scripting หรือ XSS การโจมตีประเภทนี้อนุญาตให้ผู้ไม่หวังดีฉีดโค้ดฝั่งไคลเอ็นต์ ซึ่งส่วนใหญ่มักจะเป็น JavaScript เข้าไปในหน้าเว็บที่ผู้ใช้งานเข้าชมได้
ลองจินตนาการว่ามีเว็บไซต์ที่ดูปลอดภัย แต่เมื่อเปิดขึ้นมากลับมีการทำงานแปลก ๆ นั่นอาจเป็นผลมาจากการโจมตี XSS ซึ่งแบ่งออกได้หลายประเภท
ในวันนี้จะมาเจาะลึกรูปแบบที่แตกต่างออกไป นั่นคือ DOM XSS ที่ไม่จำเป็นต้องยุ่งกับเซิร์ฟเวอร์เลย
DOM XSS คืออะไร?
DOM XSS ย่อมาจาก Document Object Model Cross-Site Scripting มันคือการโจมตี XSS ชนิดหนึ่งที่เกิดขึ้นและถูกประมวลผลทั้งหมดบนฝั่ง ไคลเอ็นต์ หรือใน เบราว์เซอร์ ของผู้ใช้งานเอง
ต่างจาก XSS ประเภทอื่น ๆ ที่เพย์โหลดอันตรายมักจะถูกส่งมาจากเซิร์ฟเวอร์ (ไม่ว่าจะผ่านการสะท้อนกลับมาทันที หรือถูกจัดเก็บไว้ก่อน)
แต่สำหรับ DOM XSS ปัญหาเกิดจากการที่ โค้ด JavaScript ฝั่งไคลเอ็นต์ ของเว็บไซต์เอง ดึงข้อมูลที่ ไม่น่าเชื่อถือ หรือ ไม่ได้ถูกตรวจสอบ มาใช้งาน แล้วนำไปแก้ไขโครงสร้างของหน้าเว็บ หรือ DOM อย่างไม่ปลอดภัย
การโจมตี DOM XSS เกิดขึ้นได้อย่างไร?
เมื่อเบราว์เซอร์โหลดหน้าเว็บ มันจะสร้างโครงสร้างที่เรียกว่า Document Object Model (DOM) ขึ้นมา ซึ่งเป็นเหมือนแผนผังของหน้าเว็บทั้งหมด และ JavaScript ของเว็บไซต์ก็มีหน้าที่ในการโต้ตอบกับ DOM นี้ เพื่อเพิ่ม ลบ หรือแก้ไขเนื้อหาต่าง ๆ
จุดอ่อนมักอยู่ใน JavaScript ที่ดึงค่าจากแหล่งข้อมูลที่ผู้ใช้งานควบคุมได้ เช่น พารามิเตอร์ใน URL (โดยเฉพาะ fragment identifier #), Local Storage, Session Storage, document.URL หรือ document.referrer
หาก JavaScript นำค่าเหล่านั้นไปเขียนลงใน DOM ด้วยฟังก์ชัน ไม่ปลอดภัย เช่น innerHTML, document.write(), หรือ eval() โดยไม่มีการตรวจสอบ ผู้โจมตีก็สามารถแทรกโค้ด JavaScript ของตัวเองให้เบราว์เซอร์ประมวลผลได้
ตัวอย่างเช่น เว็บไซต์มีสคริปต์ที่อ่านค่าจาก window.location.hash มาแสดงผลบนหน้าเว็บโดยตรง หากผู้โจมตีสร้างลิงก์ที่มี #<script>alert('XSS')</script> เมื่อผู้ใช้คลิก ลิงก์นั้นจะทำงานในเบราว์เซอร์ของผู้ใช้ทันทีโดยที่เซิร์ฟเวอร์ไม่ได้รับรู้ถึงโค้ดอันตรายนี้เลย
ทำไม DOM XSS ถึงจับยาก?
ความท้าทายของ DOM XSS คือการที่มันเกิดขึ้นภายในเบราว์เซอร์ล้วน ๆ ทำให้ระบบป้องกันฝั่งเซิร์ฟเวอร์ เช่น WAF อาจตรวจจับได้ยาก เพราะเพย์โหลดไม่เคยไปถึงเซิร์ฟเวอร์
ผลกระทบของการโจมตี DOM XSS นั้นร้ายแรงไม่ต่างจาก XSS ประเภทอื่น ๆ ผู้โจมตีสามารถขโมย คุกกี้เซสชัน ของผู้ใช้งาน เพื่อเข้าสู่ระบบในฐานะผู้ใช้งานคนนั้นได้, เปลี่ยนแปลงเนื้อหาบนหน้าเว็บ, ทำการเปลี่ยนเส้นทางไปยังเว็บไซต์อันตราย, ขโมยข้อมูลส่วนตัว, หรือแม้กระทั่งบันทึกการกดแป้นพิมพ์ของผู้ใช้งาน
การป้องกันแอปพลิเคชันจาก DOM XSS
เพื่อป้องกัน DOM XSS ต้องให้ความสำคัญกับการเขียนโค้ดฝั่งไคลเอ็นต์อย่างรัดกุม
- ตรวจสอบและกรองข้อมูล: ข้อมูลทุกชนิดที่มาจากแหล่งที่ผู้ใช้งานสามารถควบคุมได้ จะต้องถูก ตรวจสอบ (validate) และ กรอง (sanitize) อย่างละเอียดก่อนนำไปใช้ในการแก้ไข DOM
- หลีกเลี่ยงฟังก์ชันอันตราย: ควรหลีกเลี่ยงการใช้ฟังก์ชันอย่าง innerHTML, document.write(), eval(), setTimeout(), และ setInterval() ร่วมกับข้อมูลที่ไม่น่าเชื่อถือ หรือหากจำเป็นต้องใช้ ควรแน่ใจว่าได้ Escaping ข้อมูลอย่างเหมาะสมตามบริบทที่จะนำไปใช้งาน
- ใช้ Content Security Policy (CSP): กำหนดนโยบายความปลอดภัยเนื้อหา (CSP) เป็นอีกชั้นของการป้องกัน เพื่อควบคุมแหล่งที่มาของสคริปต์ สไตล์ และทรัพยากรอื่น ๆ ที่เบราว์เซอร์ได้รับอนุญาตให้โหลดและรันได้ สิ่งนี้ช่วยลดความเสี่ยงจากการรันสคริปต์ที่ไม่พึงประสงค์ได้เป็นอย่างดี
การทำความเข้าใจและป้องกัน DOM XSS เป็นสิ่งสำคัญ การเขียนโค้ดที่รัดกุมและใส่ใจในทุกรายละเอียดคือหัวใจสำคัญในการปกป้องผู้ใช้งานจากภัยคุกคามนี้