การฉีด SQL
การฉีด SQL
การฉีด SQL เป็นเทคนิคการแทรกโค้ดที่อาจทำลายฐานข้อมูลของคุณ
การฉีด SQL เป็นหนึ่งในเทคนิคการแฮ็กเว็บที่พบบ่อยที่สุด
การฉีด SQL คือการวางโค้ดที่เป็นอันตรายในคำสั่ง SQL ผ่านการป้อนข้อมูลหน้าเว็บ
SQL ในเว็บเพจ
การฉีด SQL มักเกิดขึ้นเมื่อคุณขอให้ผู้ใช้ป้อนข้อมูล เช่น ชื่อผู้ใช้/รหัสผู้ใช้ และแทนที่จะใช้ชื่อ/รหัส ผู้ใช้จะให้คำสั่ง SQL ที่คุณจะเรียกใช้บนฐานข้อมูลของคุณโดยไม่รู้ตัว
ดูตัวอย่างต่อไปนี้ซึ่งสร้าง
SELECT
คำสั่งโดยการเพิ่มตัวแปร (txtUserId) ให้กับสตริงที่เลือก ตัวแปรถูกดึงมาจากอินพุตของผู้ใช้ (getRequestString):
ตัวอย่าง
txtUserId = getRequestString("UserId");
txtSQL = "SELECT *
FROM Users WHERE UserId = " + txtUserId;
ส่วนที่เหลือของบทนี้จะอธิบายถึงอันตรายที่อาจเกิดขึ้นจากการใช้อินพุตของผู้ใช้ในคำสั่ง SQL
การฉีด SQL ตาม 1=1 เป็นจริงเสมอ
ดูตัวอย่างด้านบนอีกครั้ง จุดประสงค์ดั้งเดิมของรหัสคือการสร้างคำสั่ง SQL เพื่อเลือกผู้ใช้ด้วยรหัสผู้ใช้ที่กำหนด
หากไม่มีอะไรป้องกันผู้ใช้จากการป้อนข้อมูลที่ "ผิด" ผู้ใช้สามารถป้อนข้อมูลที่ "ฉลาด" ได้ดังนี้:
รหัสผู้ใช้:
จากนั้นคำสั่ง SQL จะมีลักษณะดังนี้:
SELECT * FROM Users WHERE UserId = 105 OR 1=1;
SQL ด้านบนถูกต้อง และจะส่งคืนแถวทั้งหมดจากตาราง "ผู้ใช้" เนื่องจาก OR 1=1จะเป็น TRUE เสมอ
ตัวอย่างข้างต้นดูอันตรายหรือไม่? จะเกิดอะไรขึ้นหากตาราง "ผู้ใช้" มีชื่อและรหัสผ่าน
คำสั่ง SQL ด้านบนนี้เหมือนกันมาก:
SELECT UserId, Name, Password
FROM Users WHERE UserId = 105 or 1=1;
แฮ็กเกอร์อาจเข้าถึงชื่อผู้ใช้และรหัสผ่านทั้งหมดในฐานข้อมูล เพียงแค่ใส่ 105 OR 1=1 ลงในช่องป้อนข้อมูล
การฉีด SQL ตาม ""="" เป็นจริงเสมอ
นี่คือตัวอย่างการเข้าสู่ระบบของผู้ใช้บนเว็บไซต์:
ชื่อผู้ใช้:
รหัสผ่าน:
ตัวอย่าง
uName = getRequestString("username");
uPass = getRequestString("userpassword");
sql = 'SELECT * FROM Users WHERE Name ="' + uName + '" AND Pass ="' + uPass +
'"'
ผลลัพธ์
SELECT * FROM Users WHERE Name ="John Doe" AND Pass ="myPass"
แฮ็กเกอร์อาจเข้าถึงชื่อผู้ใช้และรหัสผ่านในฐานข้อมูลโดยเพียงแค่แทรก " OR ""=" ลงในกล่องข้อความชื่อผู้ใช้หรือรหัสผ่าน:
ชื่อผู้ใช้:
รหัสผ่าน:
รหัสที่เซิร์ฟเวอร์จะสร้างคำสั่ง SQL ที่ถูกต้องดังนี้:
ผลลัพธ์
SELECT * FROM Users WHERE Name ="" or ""="" AND Pass ="" or ""=""
SQL ด้านบนถูกต้อง และจะส่งคืนแถวทั้งหมดจากตาราง "ผู้ใช้" เนื่องจากOR ""=""จะเป็น TRUE เสมอ
การฉีด SQL ตามคำสั่ง SQL แบบแบตช์
ฐานข้อมูลส่วนใหญ่รองรับคำสั่ง SQL แบบแบตช์
ชุดคำสั่ง SQL คือกลุ่มของคำสั่ง SQL สองคำสั่งขึ้นไป คั่นด้วยเครื่องหมายอัฒภาค
คำสั่ง SQL ด้านล่างจะส่งคืนแถวทั้งหมดจากตาราง "ผู้ใช้" จากนั้นลบตาราง "ซัพพลายเออร์"
ตัวอย่าง
SELECT * FROM Users; DROP TABLE Suppliers
ดูตัวอย่างต่อไปนี้:
ตัวอย่าง
txtUserId = getRequestString("UserId");
txtSQL = "SELECT *
FROM Users WHERE UserId = " + txtUserId;
และอินพุตต่อไปนี้:
รหัสผู้ใช้:
คำสั่ง SQL ที่ถูกต้องจะมีลักษณะดังนี้:
ผลลัพธ์
SELECT * FROM Users WHERE
UserId = 105; DROP TABLE Suppliers;
ใช้พารามิเตอร์ SQL สำหรับการป้องกัน
เพื่อป้องกันเว็บไซต์จากการแทรก SQL คุณสามารถใช้พารามิเตอร์ SQL
พารามิเตอร์ SQL คือค่าที่เพิ่มลงในแบบสอบถาม SQL ณ เวลาดำเนินการ ในลักษณะที่ควบคุม
ตัวอย่างมีดโกน ASP.NET
txtUserId = getRequestString("UserId");
txtSQL = "SELECT *
FROM Users WHERE UserId = @0";
db.Execute(txtSQL,txtUserId);
โปรดทราบว่าพารามิเตอร์จะแสดงในคำสั่ง SQL ด้วยเครื่องหมาย @
เอ็นจิ้น SQL จะตรวจสอบพารามิเตอร์แต่ละตัวเพื่อให้แน่ใจว่าถูกต้องสำหรับคอลัมน์และดำเนินการตามตัวอักษร และไม่เป็นส่วนหนึ่งของ SQL ที่จะดำเนินการ
ตัวอย่างอื่น
txtNam = getRequestString("CustomerName");
txtAdd = getRequestString("Address");
txtCit = getRequestString("City");
txtSQL = "INSERT INTO Customers (CustomerName,Address,City) Values(@0,@1,@2)";
db.Execute(txtSQL,txtNam,txtAdd,txtCit);
ตัวอย่าง
ตัวอย่างต่อไปนี้แสดงวิธีสร้างการสืบค้นแบบกำหนดพารามิเตอร์ในภาษาเว็บทั่วไปบางภาษา
เลือกคำสั่งใน ASP.NET:
txtUserId = getRequestString("UserId");
sql = "SELECT * FROM Customers WHERE CustomerId = @0";
command = new SqlCommand(sql);
command.Parameters.AddWithValue("@0",txtUserId);
command.ExecuteReader();
แทรกลงในคำสั่งใน ASP.NET:
txtNam = getRequestString("CustomerName");
txtAdd = getRequestString("Address");
txtCit = getRequestString("City");
txtSQL = "INSERT INTO Customers (CustomerName,Address,City) Values(@0,@1,@2)";
command = new SqlCommand(txtSQL);
command.Parameters.AddWithValue("@0",txtNam);
command.Parameters.AddWithValue("@1",txtAdd);
command.Parameters.AddWithValue("@2",txtCit);
command.ExecuteNonQuery();
แทรกลงในคำสั่งใน PHP:
$stmt = $dbh->prepare("INSERT INTO Customers (CustomerName,Address,City)
VALUES (:nam, :add, :cit)");
$stmt->bindParam(':nam', $txtNam);
$stmt->bindParam(':add', $txtAdd);
$stmt->bindParam(':cit', $txtCit);
$stmt->execute();