ข้ามไปยังเนื้อหาหลัก
คู่มือระบบ เนื้อหาผ่านการตรวจสอบแล้ว

การป้องกัน XSS (Cross-Site Scripting)

บทความนี้กล่าวถึง Cross-Site Scripting (XSS) ซึ่งเป็นช่องโหว่ที่ผู้ไม่ประสงค์ดีสามารถแทรกสคริปต์อันตรายเข้าไปในเว็บไซต์ได้ โดยเน้นที่สองแนวทางหลักในการป้องกันคื...

การป้องกัน XSS (Cross-Site Scripting)

หลังจากที่เราได้เรียนรู้เกี่ยวกับการป้องกัน SQL Injection, CSRF, และการจัดการรหัสผ่านอย่างปลอดภัยแล้ว อีกหนึ่งภัยคุกคามที่สำคัญต่อเว็บแอปพลิเคชันคือ Cross-Site Scripting (XSS) ซึ่งเป็นช่องโหว่ที่อนุญาตให้ผู้ไม่ประสงค์ดีสามารถแทรกสคริปต์ที่เป็นอันตราย (มักจะเป็น JavaScript) เข้าไปในเว็บไซต์ที่เหยื่อเข้าชม

ความหมายของ XSS

XSS เกิดขึ้นเมื่อเว็บแอปพลิเคชันรับข้อมูลจากผู้ใช้ (เช่น ช่องกรอกข้อมูล, URL) โดยไม่ตรวจสอบหรือทำความสะอาด (sanitize) ข้อมูลนั้นอย่างเหมาะสม ก่อนที่จะแสดงผลข้อมูลนั้นบนหน้าเว็บ หากข้อมูลนั้นมีสคริปต์ที่เป็นอันตราย สคริปต์นั้นจะถูกรันในเบราว์เซอร์ของผู้ใช้ที่เข้าชมหน้านั้น ทำให้ผู้โจมตีสามารถ:

  • ขโมย cookies และ session tokens
  • เปลี่ยนเส้นทางการเข้าชมไปยังเว็บไซต์ที่เป็นอันตราย
  • แสดงข้อความหลอกลวงเพื่อหลอกให้ผู้ใช้กรอกข้อมูลส่วนตัว
  • ติดตั้ง keyloggers เพื่อดักจับการพิมพ์ของผู้ใช้
  • และอื่นๆ อีกมากมาย

XSS แบ่งออกเป็น 3 ประเภทหลัก:

  1. Stored XSS (Persistent XSS): สคริปต์ที่เป็นอันตรายจะถูกเก็บไว้ในฐานข้อมูล (เช่น ใน comment, post) และจะถูกแสดงผลทุกครั้งที่ผู้ใช้เข้าชมหน้านั้น
  2. Reflected XSS (Non-Persistent XSS): สคริปต์ที่เป็นอันตรายจะถูกส่งผ่านทาง URL หรือ form submission และจะถูกแสดงผลทันทีเมื่อผู้ใช้คลิกที่ลิงก์หรือส่ง form นั้น
  3. DOM-based XSS: ช่องโหว่นี้เกิดขึ้นใน client-side JavaScript code โดยสคริปต์ที่เป็นอันตรายจะถูกแทรกเข้าไปใน Document Object Model (DOM) ของหน้าเว็บ

การ Sanitizing Input

การ sanitize input คือการทำความสะอาดข้อมูลที่ได้รับจากผู้ใช้ก่อนที่จะนำไปใช้งาน วิธีการที่ใช้ในการ sanitize input จะแตกต่างกันไปขึ้นอยู่กับบริบทของการใช้งาน แต่หลักการพื้นฐานคือการลบหรือแปลงอักขระที่อาจเป็นอันตราย

ตัวอย่างการ sanitize input ด้วย filter_var():

<?php
$input = $_POST['comment'];

// ลบแท็ก HTML ทั้งหมด
$sanitized_comment = filter_var($input, FILTER_SANITIZE_STRING);

// หรือ, หากต้องการอนุญาตบางแท็ก HTML:
$allowed_tags = '<p><br><strong><em>';
$sanitized_comment = strip_tags($input, $allowed_tags);

// อีกทางเลือกหนึ่งคือการ encode HTML entities
$sanitized_comment = htmlentities($input, ENT_QUOTES, 'UTF-8');

echo "Comment: " . $sanitized_comment;
?>

เหตุผลเชิงออกแบบ:

  • การใช้ filter_var() กับ FILTER_SANITIZE_STRING เป็นวิธีที่ง่ายและรวดเร็วในการลบแท็ก HTML แต่ควรระวังว่าอาจจะลบแท็กที่จำเป็นออกไปด้วย
  • การใช้ strip_tags() ช่วยให้เราสามารถกำหนดแท็ก HTML ที่ต้องการอนุญาตได้ แต่ต้องระมัดระวังในการเลือกแท็กที่อนุญาต เพราะแท็กบางแท็ก (เช่น <script>, <iframe>) อาจเป็นอันตรายได้
  • การใช้ htmlentities() เป็นวิธีที่ปลอดภัยที่สุดในการป้องกัน XSS เพราะจะแปลงอักขระพิเศษทั้งหมดเป็น HTML entities ซึ่งจะทำให้เบราว์เซอร์แสดงผลอักขระเหล่านั้นเป็นข้อความธรรมดาแทนที่จะเป็นโค้ด

แนวปฏิบัติที่ดี:

  • เลือกวิธีการ sanitize input ที่เหมาะสมกับบริบทของการใช้งาน
  • อย่าเชื่อใจข้อมูลที่ได้รับจากผู้ใช้ แม้ว่าจะเป็นข้อมูลที่มาจากผู้ใช้ที่น่าเชื่อถือ
  • sanitize input ทุกครั้งก่อนที่จะนำไปใช้งาน ไม่ว่าจะเป็นการแสดงผลบนหน้าเว็บ, การเก็บลงฐานข้อมูล, หรือการส่งไปยังระบบอื่น

การ Escaping Output

การ escaping output คือการแปลงข้อมูลที่จะแสดงผลบนหน้าเว็บให้เป็นรูปแบบที่ปลอดภัย เพื่อป้องกันไม่ให้เบราว์เซอร์ตีความข้อมูลนั้นว่าเป็นโค้ด การ escaping output เป็นสิ่งจำเป็นแม้ว่าเราจะ sanitize input แล้วก็ตาม เพราะอาจมีช่องโหว่ในการ sanitize input ที่เรามองข้ามไป

ตัวอย่างการ escaping output ด้วย htmlspecialchars():

<?php
$name = "<script>alert('Hello!')</script>";

// Escaping output
$escaped_name = htmlspecialchars($name, ENT_QUOTES, 'UTF-8');

echo "Hello, " . $escaped_name; // Output: Hello, <script>alert('Hello!')</script>
?>

ในตัวอย่างนี้ htmlspecialchars() จะแปลงอักขระพิเศษ <, >, ", ', และ & เป็น HTML entities ทำให้เบราว์เซอร์แสดงผลสคริปต์เป็นข้อความธรรมดาแทนที่จะรันสคริปต์นั้น

เหตุผลเชิงออกแบบ:

  • htmlspecialchars() เป็นฟังก์ชันที่ใช้งานง่ายและมีประสิทธิภาพในการป้องกัน XSS
  • การระบุ ENT_QUOTES จะทำให้ htmlspecialchars() แปลงทั้ง single quotes (') และ double quotes (") ซึ่งจะช่วยป้องกัน XSS ที่อาจเกิดขึ้นจากการใช้ quotes ใน attribute ของ HTML tags
  • การระบุ UTF-8 เป็น encoding จะช่วยให้ htmlspecialchars() ทำงานได้อย่างถูกต้องกับข้อมูลที่อยู่ในรูปแบบ UTF-8 ซึ่งเป็น encoding ที่นิยมใช้กันในปัจจุบัน

แนวปฏิบัติที่ดี:

  • escape output ทุกครั้งก่อนที่จะแสดงผลข้อมูลบนหน้าเว็บ ไม่ว่าจะเป็นข้อมูลที่มาจากผู้ใช้, ฐานข้อมูล, หรือระบบอื่น
  • เลือกวิธีการ escaping output ที่เหมาะสมกับบริบทของการใช้งาน
  • ใช้ template engine ที่มี built-in escaping features (เช่น Twig, Blade) เพื่อให้การ escaping output เป็นไปอย่างอัตโนมัติ

สรุป

การป้องกัน XSS เป็นสิ่งสำคัญอย่างยิ่งในการรักษาความปลอดภัยของเว็บแอปพลิเคชัน การ sanitize input และการ escape output เป็นสองแนวทางหลักที่สามารถช่วยลดความเสี่ยงจาก XSS ได้อย่างมีประสิทธิภาพ นอกจากนี้ การใช้ Content Security Policy (CSP) ซึ่งจะกล่าวถึงในบทความถัดไป ก็เป็นอีกหนึ่งแนวทางที่สามารถช่วยป้องกัน XSS ได้อย่างมีประสิทธิภาพยิ่งขึ้น

Office.in.th Custom Service

ต้องการพัฒนาระบบหรือปรับแต่งจากโครงสร้างนี้?

Office.in.th รับพัฒนาและออกแบบ Enterprise Web Application, API Integration และระบบบริหารงานภาครัฐ/เอกชน พร้อมการสนับสนุนระยะยาว

ดูบริการรับพัฒนาซอฟต์แวร์