หมวดหมู่: PHP

PHP: การใช้ htmlspecialchars() หรือ strip_tags() ป้องกัน XSSPHP: การใช้ htmlspecialchars() หรือ strip_tags() ป้องกัน XSS

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

ในภาษา PHP มีฟังก์ชันพื้นฐาน 2 ตัวที่นิยมใช้รับมือกับปัญหานี้ คือ htmlspecialchars() และ strip_tags() แต่ทั้งสองมีหลักการทำงานและจุดประสงค์ที่ต่างกันอย่างสิ้นเชิง บทความนี้จะพามาเจาะลึกการใช้งานอย่างถูกต้องครับ


ทำความรู้จัก XSS (Cross-Site Scripting)

XSS เกิดจากการที่ระบบนำข้อมูลที่ผู้ใช้ส่งเข้ามา (เช่น ความคิดเห็น, ชื่อผู้ใช้)ไปแสดงผลบนหน้าเว็บโดยตรงโดยไม่ได้ทำความสะอาด (Sanitize) หรือแปลงรหัส (Escape) ทำให้เบราว์เซอร์เข้าใจผิดว่าโค้ด <script>alert('Hacked!');</script> ที่ถูกส่งเข้ามาเป็นส่วนหนึ่งของ HTML และสั่งรันโค้ดนั้นทันที


htmlspecialchars() — เปลี่ยนแท็ก HTML ให้กลายเป็นข้อความธรรมดา

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

<?php
// ข้อมูลที่เป็นอันตรายจากผู้ใช้
$userInput = "<script>alert('XSS Attack!');</script>";

// แปลงอักขระพิเศษด้วย htmlspecialchars()
$safeOutput = htmlspecialchars($userInput, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8');

echo $safeOutput;
// ผลลัพธ์ใน HTML Source Code: &lt;script&gt;alert('XSS Attack!');&lt;/script&gt;
// ผลลัพธ์ที่แสดงบนจอเบราว์เซอร์: <script>alert('XSS Attack!');</script> (แสดงเป็นข้อความ ไม่รันสคริปต์)
?>

พารามิเตอร์สำคัญที่ไม่ควรมองข้าม

  • ENT_QUOTES: บังคับให้แปลงทั้ง อัญประกาศเดี่ยว (') และ อัญประกาศคู่ (") เพื่อป้องกัน XSS ใน HTML Attributes
  • 'UTF-8': ระบุ Character Encoding ให้ชัดเจนเพื่อป้องกันการเลี่ยงการกรองด้วย Multi-byte Encoding

strip_tags() — ลบแท็ก HTML ทิ้งทั้งหมด

strip_tags() ทำหน้าที่ ลบหรือตัดแท็ก HTML และ PHP ทั้งหมดออกจากสตริง ให้เหลือเพียงข้อความเพียวๆ เหมาะสำหรับฟิลด์ที่ไม่ต้องการให้มีโครงสร้าง HTML เล็ดลอดเข้ามาเลย เช่น ชื่อ-นามสกุล หรือเบอร์โทรศัพท์

<?php
$userInput = "<b>สวัสดี</b> <script>alert('XSS');</script>";

// ลบแท็ก HTML ทั้งหมด
$cleanText = strip_tags($userInput);

echo $cleanText;
// ผลลัพธ์: สวัสดี alert('XSS');
?>

การอนุญาตบางแท็ก (Allowed Tags)

คุณสามารถกำหนดแท็กที่ยอมให้ใช้งานได้ แต่ควรระวังอย่างยิ่งเพราะอาจเปิดช่องโหว่ให้แนบ Attribute ที่เป็นอันตรายเข้ามาได้ (เช่น <b onload="...">)

// อนุญาตให้ใช้เฉพาะ <b> และ <i>
$cleanText = strip_tags($userInput, ['b', 'i']);

ตารางเปรียบเทียบ: เลือกใช้ตัวไหนดี?

คุณสมบัติ htmlspecialchars() strip_tags()
หลักการทำงาน แปลงอักขระพิเศษเป็น HTML Entities ลบ/ตัดแท็ก HTML ทิ้งออกไปเลย
ข้อมูลดั้งเดิม เนื้อหาครบถ้วน แค่ถูกแปลงรูปแบบ แท็ก HTML ถูกลบหายไป
จุดประสงค์หลัก ป้องกัน XSS ตอน แสดงผล (Output Encoding) กรองข้อมูลตอน รับเข้า (Input Sanitization)
ความปลอดภัย XSS สูงมาก (แนะนำเป็นวิธีมาตรฐาน) ปานกลาง (อาจหลุดหากระบุ Allowed Tags)

แนวทางปฏิบัติที่ดีที่สุด (Best Practices)

  1. ยึดหลัก Escape on Output: ควรใช้ htmlspecialchars() ในขั้นตอนการนำข้อมูลออกไปแสดงผลบน HTML เสมอ ไม่ใช่แค่นำไปใช้เฉพาะตอนเก็บลง Database
  2. ห้ามใช้ strip_tags() เป็นเกราะป้องกัน XSS เพียงชั้นเดียว: แม้จะลบแท็ก <script> ได้ แต่อาจมีข้อความตกค้างที่ไม่สมบูรณ์เหลืออยู่ ซึ่งเสี่ยงต่อการนำไปใช้งานผิดประเภท
  3. สร้าง Helper Function ไว้ใช้งาน: เพื่อความสะดวกและไม่ลืมใส่ Parameter สำคัญ
function e($string) {
    return htmlspecialchars($string ?? '', ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8');
}

// วิธีนำไปใช้ในไฟล์ View / Template
echo e($userData);

อ่านเพิ่มเติม