SQL Injection คืออะไร?
SQL Injection คือการโจมตีประเภทหนึ่งที่ผู้ไม่ประสงค์ดีแทรกคำสั่ง SQL อันตรายเข้าไปใน Input ของเว็บแอปพลิเคชัน ทำให้สามารถดึงข้อมูลที่ไม่ได้รับอนุญาต เปลี่ยนแปลงข้อมูล หรือลบข้อมูลออกจากฐานข้อมูลได้ SQL Injection ติดอันดับ 1 ในผล OWASP Top 10 มาตลอดแบบผลซื่อยจากการไม่ตรวจสอบ Input ที่ผู้ใช้ส่งมา
ตัวอย่าง SQL Injection ที่พบบ่อย
Classic SQL Injection (เพื่อท Bypass Login)
หากเว็บไซต์ใช้ SQL Query แบบนี้ในหน้า Login:
-- SQL Query ปกติ
SELECT * FROM users WHERE username='$user' AND password='$pass'
-- ผู้โจมตีใส่: admin'-- เป็น username
SELECT * FROM users WHERE username='admin'--' AND password='anything'
-- ผล: เข้าสู่ภายโดยไม่ต้องใช้รหัสผู้!
ประเภทของ SQL Injection
| ประเภท | คำอธิบาย | อันตราย |
|---|---|---|
| In-band SQLi (Classic) | ดึงข้อมูลผ่านช่องที่ปรากฟูสบนหน้าเว็บ | สูงมาก |
| Blind SQLi | ไม่เห็นผลลัพธ์ตรง แต่เดา Response เพื่อสุ่มหาข้อมูล | สูง |
| Time-based Blind SQLi | ใช้ SLEEP() เพื่อตรวจสอบคำถามผ่านเวลาตอบสนอง | สูง |
| Out-of-band SQLi | ส่งข้อมูลออกผ่านช่องอื่น เช่น DNS, HTTP | ปานกลาง-สูง |
วิธีป้องกัน SQL Injection ที่มีประสิทธิภาพ
1. ใช้ Parameterized Queries / Prepared Statements
วิธีทีดีทีสุด: แยก SQL Structure ออกจาก Data ด้วย Prepared Statement:
// PHP - วิธีทีถูกต้อง (Prepared Statement)
$stmt = $pdo->prepare('SELECT * FROM users WHERE username = ? AND password = ?');
$stmt->execute([$username, $password]);
// Python - วิธีทีถูกต้อง
cursor.execute("SELECT * FROM users WHERE username = %s AND password = %s", (username, password))
// Node.js - วิธีทีถูกต้อง
db.query('SELECT * FROM users WHERE username = ? AND password = ?', [username, password], callback);
2. ใช้ ORM ที่มีการป้องกันในตัว
ORM (Object-Relational Mapping) อย่าง Hibernate (Java), SQLAlchemy (Python), Eloquent (Laravel) จะจัดการ Input Escaping โดยอัตโนมัติ ลดความเสียหายจาก SQL Injection ได้อย่างมีนัยสำคัญ
3. ตรวจสอบและ Sanitize Input
- ตรวจสอประเภทข้อมูลก่อนนำมาใช้: ตัวเลขควรเป็นตัวเลข, อีเมลควรอยู่ในรูปแบบ Email
- ประยุกต์ใช้ Whitelist แทน Blacklist (ระบุว่าอะไรอนุญาต แทนที่จะบล็อคเฉพาะสิ่งที่เป็นอันตราย)
- Escape อักขระตัยพิเศษใน SQL (เช่น ‘, “, ;, –) หากยังต้องใช้ Dynamic Query
4. ใช้ Principle of Least Privilege สำหรับ Database User
Database User ที่แอปพลิเคชันใช้งานควรมีแค่ SELECT, INSERT, UPDATE ที่จำเป็นตรงเท่านั้น ไม่ควรใหมแค่ DROP, CREATE, หรือ GRANT หากมีการโจมตี SQL Injection สำเร็จ ความเสียหายก็จะจำกัดไว้
5. ติดตั้ง WAF (Web Application Firewall)
WAF ช่วยตรวจจับและบล็อค Pattern ของ SQL Injection ก่อนที่จะถึง Application เป็นไลนด่านแรกที่ดี เครื่องมือเช่น ModSecurity, Cloudflare WAF, AWS WAF
การทดสอบ SQL Injection ด้วยตัวเอง (SQLMap)
SQLMap เป็นเครื่องมือ Open Source สำหรับตรวจสอบ SQL Injection โดยอัตโนมัติ ใช้เพื่อ Penetration Testing เพื่อค้นหาช่องหวงทางของตนเอง (ไม่ใช้โจมตีระบบอื่น เพราะผิดข่ายข้อมูล)
# ตรวจสอบ URL ว่ามีช่อง SQL Injection หรือไม่
sqlmap -u "https://yourdomain.com/login?user=test" --dbs
# ตรวจสอบเฉพาะพารามิเตอร์ที่น่าสงสัย
sqlmap -u "https://yourdomain.com/page?id=1" -p id --level=3
SQL Injection กับการรักษาความปลอดภัยบน Cloud VPS
- เปิดใช้งาน Database Audit Logging เพื่อตรวจจับคำสั่งผิดปกติ
- ไม่เปิดเผยข้อความผิดพลาด (Error Message) ที่เปิดเผยโครงสร้าง Database
- อัปเดต Framework และ Library ให้เป็นเวอร์ชันล่าสุดเสมอ
- เรียกใช้ Stored Procedures แทน Dynamic SQL หากเป็นไปได้
- ตรวจสอบ Code Review ส่วนที่ใช้ Database Query อย่างสม่ำเสมอ
สรุป
SQL Injection ยังคงเป็นภัยคุกคามอันดับต้นๆ ของเว็บแอปพลิเคชัน การใช้ Parameterized Queries หรือ Prepared Statement คือวิธีป้องกันที่ดีทีสุด ร่วมกับการติดตั้ง WAF และการใช้ Least Privilege สำหรับ Database User จะช่วยลดความเสียหายได้อย่างมีประสิทธิภาพ

