Thứ Ba, 12 tháng 1, 2021

SQL Injection

SQL Injection

SQL injection là một kỹ thuật chèn mã có thể phá hủy cơ sở dữ liệu của bạn.

SQL injection là một trong những kỹ thuật hack web phổ biến nhất.

SQL injection là vị trí của mã độc hại trong các câu lệnh SQL, thông qua đầu vào trang web.


SQL trong các trang web

Việc chèn SQL thường xảy ra khi bạn yêu cầu người dùng nhập vào, như tên người dùng / userrid của họ và thay vì tên / id, người dùng cung cấp cho bạn một câu lệnh SQL mà bạn sẽ vô tình chạy trên cơ sở dữ liệu của mình.

Hãy xem ví dụ sau đây tạo câu lệnh SELECT bằng cách thêm một biến (txtUserId) vào một chuỗi chọn. Biến được tìm nạp từ đầu vào của người dùng (getRequestString):

Thí dụ

txtUserId = getRequestString("UserId");
txtSQL = "SELECT * FROM Users WHERE UserId = " + txtUserId;

Phần còn lại của chương này mô tả những nguy cơ tiềm ẩn khi sử dụng đầu vào của người dùng trong các câu lệnh SQL.


SQL Injection dựa trên 1 = 1 luôn đúng

Nhìn lại ví dụ trên. Mục đích ban đầu của mã là tạo một câu lệnh SQL để chọn một người dùng, với một id người dùng nhất định.

Nếu không có gì ngăn người dùng nhập "sai" đầu vào, người dùng có thể nhập một số đầu vào "thông minh" như sau:

Tên người dùng: 

Sau đó, câu lệnh SQL sẽ giống như sau:

SELECT * FROM Users WHERE UserId = 105 OR 1=1;

SQL ở trên là hợp lệ và sẽ trả về TẤT CẢ các hàng từ bảng "Người dùng", vì OR 1 = 1 luôn là TRUE.

Ví dụ trên có nguy hiểm không? Điều gì sẽ xảy ra nếu bảng "Người dùng" chứa tên và mật khẩu?

Câu lệnh SQL ở trên giống như sau:

SELECT UserId, Name, Password FROM Users WHERE UserId = 105 or 1=1;

Một tin tặc có thể có quyền truy cập vào tất cả tên người dùng và mật khẩu trong cơ sở dữ liệu, bằng cách chỉ cần chèn 105 OR 1 = 1 vào trường đầu vào.

SQL Injection dựa trên "" = "" luôn đúng

Đây là một ví dụ về đăng nhập của người dùng trên một trang web:

Tên tài khoản:

Mật khẩu:

Thí dụ

uName = getRequestString("username");
uPass = getRequestString("userpassword");

sql = 'SELECT * FROM Users WHERE Name ="' + uName + '" AND Pass ="' + uPass + '"'

Kết quả

SELECT * FROM Users WHERE Name ="John Doe" AND Pass ="myPass"

Một tin tặc có thể có quyền truy cập vào tên người dùng và mật khẩu trong cơ sở dữ liệu bằng cách chỉ cần chèn "OR" "=" vào hộp văn bản tên người dùng hoặc mật khẩu:

Tên tài khoản:

Mật khẩu:

Mã tại máy chủ sẽ tạo một câu lệnh SQL hợp lệ như sau:

Kết quả

SELECT * FROM Users WHERE Name ="" or ""="" AND Pass ="" or ""=""

SQL ở trên là hợp lệ và sẽ trả về tất cả các hàng từ bảng "Người dùng", vì OR "" = "" luôn là TRUE.


SQL Injection dựa trên các câu lệnh SQL theo lô 

Hầu hết các cơ sở dữ liệu đều hỗ trợ câu lệnh SQL theo lô.

Một loạt câu lệnh SQL là một nhóm gồm hai hoặc nhiều câu lệnh SQL, được phân tách bằng dấu chấm phẩy.

Câu lệnh SQL bên dưới sẽ trả về tất cả các hàng từ bảng "Người dùng", sau đó xóa bảng "Nhà cung cấp".

Thí dụ

SELECT * FROM Users; DROP TABLE Suppliers

Hãy xem ví dụ sau:

Thí dụ

txtUserId = getRequestString("UserId");
txtSQL = "SELECT * FROM Users WHERE UserId = " + txtUserId;

Và đầu vào sau:

Tên người dùng: 

Câu lệnh SQL hợp lệ sẽ giống như sau:

Kết quả

SELECT * FROM Users WHERE UserId = 105DROP TABLE Suppliers;

Sử dụng tham số SQL để bảo vệ

Để bảo vệ một trang web khỏi SQL injection, bạn có thể sử dụng các tham số SQL.

Tham số SQL là các giá trị được thêm vào truy vấn SQL tại thời điểm thực thi, theo cách được kiểm soát.

Ví dụ về ASP.NET Razor

txtUserId = getRequestString("UserId");
txtSQL = "SELECT * FROM Users WHERE UserId = @0";
db.Execute(txtSQL,txtUserId);

Lưu ý rằng các tham số được biểu diễn trong câu lệnh SQL bằng dấu @.

Công cụ SQL kiểm tra từng tham số để đảm bảo rằng nó đúng với cột của nó và được xử lý theo nghĩa đen, và không phải là một phần của SQL được thực thi.

Một vi dụ khac

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);

Ví dụ

Các ví dụ sau đây cho thấy cách xây dựng truy vấn được tham số hóa trong một số ngôn ngữ web phổ biến.

CHỌN BÁO CÁO TRONG ASP.NET:

txtUserId = getRequestString("UserId");
sql = "SELECT * FROM Customers WHERE CustomerId = @0";
command = new SqlCommand(sql);
command.Parameters.AddWithValue("@0",txtUserId);
command.ExecuteReader();

CHÈN VÀO BÁO CÁO TRONG 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();

CHÈN VÀO BÁO CÁO TRONG 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();
==================================
KẾT NỐI VỚI CHUYÊN GIA TRẦN VĂN BÌNH:
📧 Mail: binhoracle@gmail.com
☎️ Mobile: 0902912888
⚡️ Skype: tranbinh48ca
👨 Facebook: https://www.facebook.com/BinhOracleMaster
👨 Inbox Messenger: https://m.me/101036604657441 (profile)
👨 Fanpage: https://www.facebook.com/tranvanbinh.vn
👨 Inbox Fanpage: https://m.me/tranvanbinh.vn
👨👩 Group FB: https://www.facebook.com/groups/DBAVietNam
👨 Website: https://www.tranvanbinh.vn
👨 Blogger: https://tranvanbinhmaster.blogspot.com
🎬 Youtube: http://bit.ly/ytb_binhoraclemaster
👨 Tiktok: https://www.tiktok.com/@binhoraclemaster?lang=vi
👨 Linkin: https://www.linkedin.com/in/binhoracle
👨 Twitter: https://twitter.com/binhoracle
👨 Địa chỉ: Tòa nhà Sun Square - 21 Lê Đức Thọ - Phường Mỹ Đình 1 - Quận Nam Từ Liêm - TP.Hà Nội

#OracleTutorial #OracleDBA #OracleDatabaseAdministration #học oracle database #oca #ocp #tự học oracle

ĐỌC NHIỀU

Trần Văn Bình - Oracle Database Master