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 management และ sql injection attrack คือ

SQL Injection คืออะไร?

SQL Injection (Structured Query Language Injection) หรือในภาษาไทย การแทรกคำสั่ง SQL เข้าไปในระบบ คือหนึ่งในการโจมตีทางไซเบอร์ที่ผู้โจมตีแทรกคำสั่ง SQL ผ่านทางช่องรับข้อมูลออนไลน์ เช่น ช่องล็อกอิน, ช่องค้นหา, ฟอร์มส่งคอมเมนต์, การดาวน์โหลด หรือ การอัปโหลดไฟล์ โดยผู้โจมตีจะแทรกคำสั่งที่บังคับให้ระบบฐานข้อมูลทำงานตามคำสั่งที่ผู้โจมตีต้องการ เช่น เข้าถึงข้อมูลลับในฐานข้อมูล, เปลี่ยนแปลง หรือลบข้อมูลและผู้โจมตียังสามารถเข้าควบคุมระบบฐานข้อมูลทั้งหมดของเหยื่อได้

แล้ว SQL มีคำสั่งกี่ประเภท?

SQL ที่ย่อมาจาก Structured Query Language คือ ภาษามาตรฐานที่ใช้ในการจัดการกับฐานข้อมูลซึ่งมีคำสั่งหลายประเภทดังนี้

  1. ดึงข้อมูล (Query / SELECT)

Ex : SELECT * FROM employees WHERE department = 'Sales';

  1. เพิ่มข้อมูล (INSERT)

INSERT INTO employees (name, department) VALUES ('xxxx', 'yyyy');

  1. แก้ไขข้อมูล (UPDATE)

UPDATE employees SET salary = 50000 WHERE id = 3;

  1. ลบข้อมูล (DELETE)

DELETE FROM employees WHERE id = 3;

  1. จัดการโครงสร้างของฐานข้อมูล(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 แบ่งเป็น In-band SQLi, Blind SQLi และ Out-of-band SQLi โดย In-band SQLi แบ่งย่อยเป็น Error-based SQLi และ Union-based SQLi ส่วน Blind SQLi แบ่งย่อยเป็น Boolean-based SQLi และ Time-based SQL และ sql enterprise

วิธีป้องกัน 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 ซ้ำๆ
  • ใช้ SIEMIDS/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%