SQL Injection คืออะไร? ทำไมทุกองค์กรต้องเรียนรู้?
รู้หรือไม่ว่า การแฮ็กกว่า 80% เกิดจาก “ข้อมูลล็อกอินที่ถูกขโมยหรือถูกนำกลับมาใช้ซ้ำ”?
เพียงการโจมตีแบบ SQL Injection ครั้งเดียว ก็สามารถขโมยรหัสผ่าน หมายเลขบัตรเครดิต หรือข้อมูลสำคัญของคุณได้ และในปี 2022 ช่องโหว่ SQL Injection เป็นสาเหตุของช่องโหว่ร้ายแรงบนเว็บแอปทั่วโลกถึง 33%
SQL Injection คือ เป็นหนึ่งในปัญหาที่ทีม SOC ต้องเจออยู่เสมอ และต้องหาวิธีป้องกัน SQL ไม่ให้เกิดขึ้นซ้ำ การเขียนโค้ดให้ปลอดภัยตั้งแต่แรกจะช่วยลดโอกาสที่โค้ดอันตรายจะถูกแทรกเข้ามาในระบบ สาเหตุหลักของการโจมตีแบบนี้คือการที่ระบบไม่แยก “ข้อมูลที่ผู้ใช้กรอก” ออกจาก “คำสั่งของโปรแกรม” อย่างเข้มงวด ทำให้ผู้โจมตีสามารถใส่โค้ดแปลกปลอมเข้าไปในข้อมูลที่ส่งเข้ามาได้ และเมื่อไม่มีระบบแยกข้อมูลอย่างปลอดภัย แอปพลิเคชันอาจ run SQLคำสั่งอันตรายที่ผู้โจมตีแทรกไว้โดยไม่รู้ตัว
ดังนั้น การเข้าใจว่า SQL injection attack คือ,ประเภทของ SQL Injection และ SQL Injection วิธีป้องกัน ไม่เพียงช่วยเสริมความปลอดภัยให้ระบบฐานข้อมูลเท่านั้น แต่ยังเป็นก้าวสำคัญในการสร้างระบบที่มั่นคง ปลอดภัย และเชื่อถือได้ในระยะยาว
SQL Injection คืออะไร?
SQL Injection (Structured Query Language Injection) หรือในภาษาไทย การแทรกคำสั่ง SQL เข้าไปในระบบ คือหนึ่งในการโจมตีทางไซเบอร์ที่ผู้โจมตีแทรกคำสั่ง SQL ผ่านทางช่องรับข้อมูลออนไลน์ เช่น ช่องล็อกอิน, ช่องค้นหา, ฟอร์มส่งคอมเมนต์, การดาวน์โหลด หรือ การอัปโหลดไฟล์ โดยผู้โจมตีจะแทรกคำสั่งที่บังคับให้ระบบฐานข้อมูลทำงานตามคำสั่งที่ผู้โจมตีต้องการ เช่น เข้าถึงข้อมูลลับในฐานข้อมูล, เปลี่ยนแปลง หรือลบข้อมูลและผู้โจมตียังสามารถเข้าควบคุมระบบฐานข้อมูลทั้งหมดของเหยื่อได้
แล้ว SQL มีคำสั่งกี่ประเภท?
SQL ที่ย่อมาจาก Structured Query Language คือ ภาษามาตรฐานที่ใช้ในการจัดการกับฐานข้อมูลซึ่งมีคำสั่งหลายประเภทดังนี้
- ดึงข้อมูล (Query / SELECT)
Ex : SELECT * FROM employees WHERE department = 'Sales';
- เพิ่มข้อมูล (INSERT)
INSERT INTO employees (name, department) VALUES ('xxxx', 'yyyy');
- แก้ไขข้อมูล (UPDATE)
UPDATE employees SET salary = 50000 WHERE id = 3;
- ลบข้อมูล (DELETE)
DELETE FROM employees WHERE id = 3;
- จัดการโครงสร้างของฐานข้อมูล(DDL – Data Definition Language)
CREATE TABLE users (id INT, username VARCHAR(50), password VARCHAR(50));
ดังนั้นเพราะ SQL เป็นหัวใจในการจัดการข้อมูลทั้งหมดของระบบสารสนเทศทุกประเภทดังนั้น การเรียนรู้ว่าอะไรทำให้เกิด SQL injection, SQL injection มีกี่ประเภท และวิธีป้องกันการเกิด SQL injection จึงเป็นสิ่งสำคัญในการดูแลรักษาระบบสารสนเทศ
การเขียน SQL ที่ทำให้เสี่ยงต่อการถูกโจมตี
การเขียน SQL แบบไม่ปลอดภัยคือสาเหตุสำคัญที่ทำให้เกิดช่องโหว่ SQL Injectionซึ่งจะเกิดขึ้นเมื่อเกิดการผสมผสานระหว่างโครงสร้างคำสั่ง SQL กับ ข้อมูลจากผู้ใช้ โดยตรง แทนที่จะแยกกันอย่างชัดเจน ซึ่งหาก การเขียน SQL ของระบบสารสนเทศไม่ปลอดภัยก็จะทำให้เกิดช่องโหว่ได้ง่ายขึ้น ดังนั้นมาดูกันว่าการเขียนที่ไม่ปลอดภัยเปนยังไง
- การต่อสตริง (String Concatenation) โดยตรงกับค่าจากผู้ใช้
การเอาค่า username, id, search หรือพารามิเตอร์อื่น ๆ มาต่อรวมกับ SQL โดยตรง เช่น:
const query = "SELECT * FROM users WHERE username = '" + req.body.username + "' AND password = '" + req.body.password + "'";db.query(query, ...);
การเขียน SQL แบบนี้เสี่ยงเพราะ ถ้าผู้โจมตีส่งค่า username เป็น admin' -- ส่วนที่เหลือของคำสั่งอาจถูกทำให้เป็นคอมเมนต์ หรือเขาอาจส่ง payload ที่เพิ่ม OR 1=1 ทำให้สามารถล้อกอินได้ตลอดเวลา
- สร้างคำสั่ง SQL ที่ไดนามิกจาก input (Dynamic SQL) โดยไม่ผ่านการคัดกรอง
ในบางกรณีระบบต้องอนุญาตให้ผู้ใช้กำหนด ORDER BY, LIMIT, column หรือเงื่อนไขค้นหาเหล่านี้ด้วยต้นเอง โดยถ้าหากระบบนำค่าพวกนี้ไปต่อกับ SQL โดยไม่ตรวจสอบจะเปิดทางให้ถูกโจมตีโดยผู้โจมตีอาจใส่ name; DROP TABLE users; -- หรือใส่ expression อันตรายได้
เช่น : const sql = `SELECT * FROM products ORDER BY ${req.query.sort}`;
- ใช้ raw SQL ใน ORM โดยไม่ parameterize
ORM บางตัวอนุญาตให้ run raw SQL เพราะสะดวกกว่า แต่ถ้าใส่ input ลงไปโดยตรงก็ทำให้เกิดความเสี่ยงเช่น
db.raw(`SELECT * FROM users WHERE email = '${email}'`);
- เก็บรหัสผ่าน หรือ ข้อมูลลับและนำไปเปรียบเทียบแบบ SQL (Plain-text password)
การใช้ SQL เพื่อเปรียบเทียบรหัสผ่านโดยตรงพร้อมกับเก็บรหัสผ่านเป็น plain text ทำให้โจมตีง่ายและร้ายแรงมาก
- Stored procedures ที่ยังคงต่อสตริงภายใน
แม้การใช้ Stored Procedure จะดูปลอดภัย แต่ถ้าขั้นตอนภายในนำ input มาต่อสตริงแล้วรัน dynamic SQL ก็ยังทำให้เกิดความเสี่ยงอยู่ดี
- การเผยข้อมูลผ่าน error messages
โค้ดที่จับข้อผิดพลาดของข้อมูลแล้วส่งข้อความ error ให้ผู้ใช้โดยตรง อาจทำให้เกิดการเปิดเผยโครงสร้างของฐานข้อมูล, ชนิดของตาราง หรือข้อมูลภายในตัวแปร SQL ทำให้ผู้โจมตีใช้ข้อมูลนี้ออกแบบ payload ได้ง่ายขึ้น
- บัญชีฐานข้อมูลที่มีสิทธิ์สูงเกินจำเป็น
ถ้าแอปเชื่อมต่อ user ที่มีสิทธิ์ DROP, ALTER, หรือ CREATE ซึ่งอาจจะทำให้มีช่องโหว่แม้เล็กน้อยแต่ผู้โจมตีก็โจมตีถึงขั้นทำลายระบบได้
- การรับข้อมูลจากหลายช่องทางโดยไม่ตรวจสอบ
ไม่ได้มีแค่ฟอร์มเว็บเท่านั้น ค่าจาก HTTP headers, cookies, หรือไฟล์ที่อัพโหลดก็ถือเป็นข้อมูลจากภายนอกที่ไม่น่าเชื่อถือ เพราะถ้าหากระบบนำค่าพวกนี้ไปประกอบ SQL โดยตรง ก็สามารถทำให้เกิดการโจมตีได้เหมือนกัน
- เก็บข้อมูลที่เก็บไว้ใช้ภายหลัง
บางครั้ง input ที่ถูกตรวจสอบว่าปลอดภัยตั้งแต่ตอนเก็บเมื่อถูกนำมาใช้ภายหลังอาจเกิด second-order injection ได้
- Logging หรือการนำข้อมูลกลับมาใช้อัตโนมัติ
การบันทึกข้อมูลลง log เพื่อนำไป parse แล้วส่งคำสั่งเป็น SQLโดยไม่ตรวจสอบอีกครั้งทำให้เกิดความเสี่ยงในการถูกโจมตี
ประเภทของ SQL Injection
การโจมตีแบบเห็นผลทางเดียว (In-band SQLi)
เป็นการโจมตีแบบที่ผู้โจมตีจะส่งข้อมูลหรือ payload กลับผ่านช่องทางเดิมที่ส่งคำขอ โดยจะได้รับข้อมูลจากช่องทางนั้นโดยตรง ทำให้การดึงข้อมูลจากเหยื่อง่ายรวดเร็วและตรงไปตรงมา โดยจะแบ่งออกเป็น 2 ประเภทหลักๆนั่นก็คือ
- Error-based SQLi : เป็น SQL Injection attack ที่ผู้โจมตีจงใจทำให้เกิดข้อผิดพลาดในฐานข้อมูลซึ่งเมื่อทำแบบนี้จะทำให้ผู้โจมตีสามารถเห็นโครงสร้างของแหล่องข้อมูลได้
- Union-based SQLi : ผู้โจมตีจะใช้คำสั่ง union เพื่อรวมหลายๆคำสั่งเข้าด้วยกันโดยจะทำให้ ผู้โจมตีสามารถขโมยข้อมูลบางอย่างจากการรวมคำสั่งนี้
การสอบถามแบบมองไม่เห็นผลลัพธ์โดยตรง (Inferential / Blind SQLi)
เป็นการโจมตีที่ผู้โจมตีไม่ได้รับข้อมูลกลับจากฐานข้อมูลโดยตรงแต่จะได้รับข้อมูลจากการสังเกตความผิดปกติของคำสั่งของแอป เช่น ความต่างของ response หรือเวลาตอบกลับ การโจมตีแบบนี้มักใช้เวลานานกว่าการโจมตีแบบเห็นผลทางเดียว(In-band SQLi) แต่ในทางกลับกันก็สามารถได้เหตุผลในเชิงลึกที่มีประโยชน์มากกว่า โดยถูกแบ่งออกเป็น 2 ประเภทที่พบบ่อยได้แก่
- Boolean-based (Boolean Blind) : ผู้โจมตีไม่ได้รับข้อมูลจากฐานข้อมูลโดยตรงแต่ส่งคำขอที่แตกต่างกันเพื่อสังเกตความแตกต่างของผลลัพธ์จนกว่าจะได้ข้อมูลที่ต้องการ
- Time-based (Time Blind) : ผู้โจมตีจะไม่ได้รับข้อมูลโดยตรงแต่ใช้วิธีส่งคำขอเพื่อหน่วงเวลาเพื่อสังเกตเวลาตอบกลับ เพื่อตีความข้อมูลที่ต้องการ เพราะฉะนั้นการโจมตีประเภทนี้อาศัยความต่างของเวลาเป็นช่องทางสื่อสารระหว่างแอปกับผู้โจมตี
Out-of-band SQLi (OOB)
เป็น SQL Injection attack ที่ผู้โจมตีสั่งให้ฐานข้อมูล ส่งข้อมูลออกไปยังช่องทางภายนอก ที่ผู้โจมตีควบคุม เช่น DNS request, HTTP callback, หรือช่องทางเครือข่ายอื่น แทนที่จะผลลัพธ์ response กลับทางช่องทางเดิม เทคนิคนี้มักถูกใช้เมื่อ In-band/Blind ถูกปิดกั้นหรือไม่สะดวก แต่เซิร์ฟเวอร์/DB ยังสามารถติดต่อออกไปภายนอกได้
วิธีป้องกัน SQL Injection และ วิธีป้องกัน SQL Injection PHP
การเข้าใจวิธีป้องกันที่ถูกต้อง จะทำให้เราสามารถลดความเสี่ยงนี้ได้อย่างมีประสิทธิภาพโดยมีหลักการอยู่หลักๆ 15 ข้อ ดังนี้
- แยกข้อมูลออกจากคำสั่ง SQL : ใช้ Prepared Statements / Parameterized Queries เสมอ หลีกเลี่ยงการเอา input ไปต่อเป็นสตริงใน SQL
- หลีกเลี่ยงการใช้ input เป็นส่วนของโครงสร้าง SQL โดยตรง
- Validate & Sanitize ข้อมูลก่อนใช้งาน
- ระมัดระวังในการใช้ ORM/Query Builder
- เก็บรหัสผ่านอย่างปลอดภัย หลีกเลี่ยงการเก็บรหัสเป็น plain text
- ซ่อน error messages หลีกเลี่ยงการให้ข้อมูลเชิงเทคนิคต่อผู้ใช้
- สังเกตและแจ้งเตือนความผิดปกติ เช่น request ซ้ำๆ
- ใช้ SIEM, IDS/IPS และ WAF เป็นอุปกรณ์เสริม
- จำกัด outbound access ของ DB server และ ปิดฟีเจอร์ DB ที่เรียก shell หรือ เครือข่ายหากไม่จำเป็น
- ตรวจสอบว่าฟังก์ชันหรือสคริปต์เหล่านี้ไม่ประกอบ SQLโดยใช้ค่าที่มาจาก DB โดยตรง
- หา pattern การต่อ string ที่เสี่ยง
- Static Analysis (SAST) หา pattern การต่อ string ที่เสี่ยง
- Dynamic Analysis (DAST) / Pen-testing ทดสอบช่องโหว่จากภายนอก
- เพิ่ม test ใน CI และ second-order
- บังคับ PR review สำหรับทุก code path ที่เรียก DB โดยเฉพาะ raw SQL
การป้องกัน SQL injection คือข้อปฏิบัติที่เริ่มตั้งแต่ระบบตั้งแต่ระดับโค้ดจนถึงโครงสร้างพื้นฐาน ถ้าหากผู้ดูแลตรวจสอบและทำตามข้อปฎิบัติอย่างสม่ำเสมอจะทำให้ลดและป้องกันการเกิด SQL injection ได้
SIEM ช่วยรับมือกับการโจมตี SQL Injection ได้อย่างไร?
เพื่อตรวจจับและลดผลกระทบจากการโจมตีแบบ SQL Injection (SQLi) ผู้วิเคราะห์ความปลอดภัยจำเป็นต้องใช้เครื่องมือรักษาความปลอดภัยของเครือข่ายที่ครอบคลุม ที่สามารถวิเคราะห์และเชื่อมโยงข้อมูล log จากเซิร์ฟเวอร์เว็บและฐานข้อมูลได้อย่างมีประสิทธิภาพด้วยเครื่องมือ SIEM อย่าง ManageEngine Log360 คุณสามารถ:
- ตรวจสอบกิจกรรมที่เกี่ยวข้องกับ DML (Data Manipulation Language) และ DDL (Data Definition Language)
- ติดตามการเปลี่ยนแปลงบัญชีผู้ใช้ในเซิร์ฟเวอร์ฐานข้อมูล
- ตรวจสอบกิจกรรมการใช้งานบนเซิร์ฟเวอร์ฐานข้อมูล
- ติดตามการใช้งานเซิร์ฟเวอร์เว็บ ข้อผิดพลาด และเหตุการณ์สำคัญต่างๆ
- ตรวจจับและรับการแจ้งเตือนเกี่ยวกับพฤติกรรมน่าสงสัยและการโจมตีด้านความปลอดภัย เช่น SQL Injection หรือ Cross-site Scripting ที่มุ่งเป้าไปยังแอปพลิเคชันของคุณ
ปกป้ององค์กรของคุณจาก SQL injection attack ลงทะเบียนเพื่อรับเดโม่ ของ ManageEngine Log360 ซึ่งเป็นโซลูชัน SIEM แบบครบวงจร สำหรับคุณที่มาพร้อมความสามารถด้านความปลอดภัยของข้อมูลและคลาวด์
ติดตามข้อมูลเพิ่มเติม
Linkedin : https://www.linkedin.com/company/manageenginethailand
facebook : https://www.facebook.com/manageenginethailand
references : SQL Injection เป็นสาเหตุของช่องโหว่ร้ายแรงบนเว็บแอปทั่วโลกถึง 33%

