SQL Injection เป็นการโจมตีที่ใช้ประโยชน์จากจุดอ่อนในแอปพลิเคชันที่มีการรับข้อมูลจากผู้ใช้โดยตรงแล้วนำไปใช้ในคำสั่ง SQL โดยไม่ได้กรองหรือตรวจสอบข้อมูลอย่างถูกต้อง ทำให้ผู้โจมตีสามารถแทรกหรือแก้ไขคำสั่ง SQL เพื่อเข้าถึงหรือแก้ไขข้อมูลในฐานข้อมูลโดยไม่ได้รับอนุญาต
ตัวอย่างของ SQL Injection
การโจมตี SQL Injection มีหลายรูปแบบ ขึ้นอยู่กับเป้าหมายและโครงสร้างของฐานข้อมูล เราจะมาดูตัวอย่างหลัก ๆ ที่พบบ่อยๆ
- การโจมตีแบบพื้นฐาน (Classic SQL Injection)
- การแทรกหลายคำสั่ง (Union-based SQL Injection)
- การปรับโครงสร้างคำสั่ง (Blind SQL Injection)
สร้างตารางตัวอย่าง
ก่อนที่เราจะเข้าไปดูตัวอย่างการโจมตี เรามาเริ่มด้วยการสร้างตารางตัวอย่างกันก่อนนะครับ
คำสั่ง SQL เพื่อสร้างตารางและแทรกข้อมูล
-- สร้างตารางผู้ใช้งาน
CREATE TABLE users (
id INT PRIMARY KEY AUTO_INCREMENT,
username VARCHAR(50),
password VARCHAR(50)
);
-- แทรกข้อมูลตัวอย่าง
INSERT INTO users (username, password) VALUES ('admin', 'admin123');
INSERT INTO users (username, password) VALUES ('john', 'password1');
INSERT INTO users (username, password) VALUES ('jane', 'password2');ข้อมูลในตาราง users

Classic SQL Injection (การโจมตีพื้นฐาน)
ผู้โจมตีอาจใช้การกรอกข้อมูลในฟอร์ม Login ที่ไม่ได้กรองข้อมูลอย่างถูกต้อง เช่น
-- คำสั่ง SQL ที่ระบบใช้ในการตรวจสอบการเข้าสู่ระบบ
SELECT * FROM users WHERE username = 'admin' AND password = 'password';ถ้าผู้โจมตีกรอกข้อมูลดังนี้:
- Username:
admin - Password:
' OR '1' = '1
คำสั่ง SQL จะเปลี่ยนเป็น
SELECT * FROM users WHERE username = 'admin' AND password = '' OR '1' = '1';เนื่องจาก '1' = '1' เป็นจริงตลอดเวลา คำสั่งนี้จะคืนผลลัพธ์ที่ดึงข้อมูลของผู้ใช้ทั้งหมดออกมา ทำให้ผู้โจมตีสามารถล็อกอินได้สำเร็จโดยไม่รู้รหัสผ่านที่แท้จริง
Union-based SQL Injection (การแทรกหลายคำสั่ง)
การโจมตีแบบนี้ใช้คำสั่ง UNION เพื่อดึงข้อมูลจากตารางอื่นที่อาจไม่เกี่ยวข้องโดยตรง ตัวอย่างเช่น
-- คำสั่ง SQL ที่อาจใช้แสดงข้อมูลผู้ใช้
SELECT id, username FROM users WHERE username = 'john';ถ้าผู้โจมตีกรอกข้อมูลดังนี้
- Username:
' UNION SELECT null, database() --
คำสั่ง SQL จะเปลี่ยนเป็น
SELECT id, username FROM users WHERE username = 'john' UNION SELECT null, database();ผลลัพธ์จะรวมข้อมูลจากตาราง users กับชื่อของฐานข้อมูลปัจจุบัน
ในกรณีนี้ ผู้โจมตีได้ข้อมูลชื่อฐานข้อมูลออกมาโดยใช้คำสั่ง UNION
Blind SQL Injection (การโจมตีแบบปรับโครงสร้างคำสั่ง)
การโจมตีแบบ Blind SQL Injection ใช้เมื่อผู้โจมตีไม่สามารถดูผลลัพธ์ของคำสั่ง SQL ได้โดยตรง แต่สามารถใช้คำสั่งเพื่อให้เกิดความแตกต่างในการตอบสนอง ตัวอย่างเช่น
-- ระบบอาจใช้คำสั่งนี้เพื่อตรวจสอบว่าผู้ใช้มีอยู่ในระบบหรือไม่
SELECT * FROM users WHERE username = 'admin' AND password = 'admin123';ผู้โจมตีสามารถใช้เงื่อนไขที่ซับซ้อนเพื่อดูว่าเงื่อนไขเป็นจริงหรือไม่ เช่น:
- Username:
admin - Password:
' AND (SELECT LENGTH(database())) = 8 --
คำสั่ง SQL จะเปลี่ยนเป็น
SELECT * FROM users WHERE username = 'admin' AND password = '' AND (SELECT LENGTH(database())) = 8;หากชื่อฐานข้อมูลมีความยาวเป็น 8 ตัวอักษร ระบบอาจตอบกลับด้วยผลลัพธ์ที่แตกต่างไป ทำให้ผู้โจมตีสามารถคาดเดาข้อมูลได้ทีละขั้นตอน
วิธีป้องกัน SQL Injection
1. การใช้ Prepared Statements (Parameterized Queries): โดยการใช้คำสั่ง SQL ที่ไม่รวมข้อมูลจากผู้ใช้เข้ากับโครงสร้างคำสั่ง SQL โดยตรง เช่น
cursor.execute("SELECT * FROM users WHERE username = ? AND password = ?", (username, password))2. การกรองข้อมูล (Input Validation): ตรวจสอบข้อมูลที่ผู้ใช้กรอกให้ถูกต้อง เช่น การปฏิเสธอักขระพิเศษที่ไม่ควรอยู่ในข้อมูล
3. การใช้ ORM (Object Relational Mapping): ใช้เครื่องมือ ORM เช่น SQLAlchemy หรือ Django ORM เพื่อจัดการคำสั่ง SQL ให้ปลอดภัยจาก SQL Injection
