SQL Injection Nguy Hiểm Thế Nào Với Website?

SQL Injection Nguy Hiểm Thế Nào Với Website?

Ở trong Series này mình sẽ chỉ cho các bạn các lỗi bảo mật ở trên các trang web chưa tốt. Từ đó chúng ta biết cách fix cho website của mình. Mong các bạn thích và ủng hộ Series này.

SQL Injection (SQLi) là gì ??

Theo như các bạn đã biết, đa số các website bây giờ đều có users tạo tài khoản trên đó và sử dụng. Mà các thông tin đó lại chứa trong Database, nên khi các bạn lập trình với MySQL hoặc PostgreSQL hoặc là MS SQL sẽ gây ra các bug ảnh hưởng đến app, một trong số đó là SQL Injection.

SQL injection (hay còn được gọi là SQLi) là sử dụng những lỗ hổng trong các kênh đầu vào (input) của website để nhắm mục tiêu vào cơ sở dữ liệu nằm trong phần phụ trợ của ứng dụng web, nơi lưu giữ những thông tin nhạy cảm và có giá trị nhất. Chúng có thể được kẻ tấn công sử dụng để ăn cắp hoặc xáo trộn dữ liệu, cản trở sự hoạt động của các ứng dụng, và, trong trường hợp xấu nhất, nó có thể chiếm được quyền truy cập quản trị vào máy chủ cơ sở dữ liệu, chiếm quyền quản trị, xóa hết dữ liệu,...

Khi tính đến mức độ nguy hiểm của SQLi, điều quan trọng hơn cả đó là việc bị đánh cắp các thông tin nhạy cảm như thông tin cá nhân như số điện thoại, địa chỉ và chi tiết thẻ tín dụng, vv...

Dưới đây là những gì bạn cần biết về tấn công SQL Injection và cách bảo vệ website của bạn khỏi SQLi.

Website bị tấn công như thế nào?

Có thể tìm các trang web cho phép submit dữ liệu ở bất kì một trình tìm kiếm nào trên mạng, chẳng hạn như các trang login, search, feedback, ...

Giả dụ chúng ta có một Form login như thế này:

Giờ chúng ta thử đăng nhập:

Email: [email protected]

Mật khẩu: password

Hmm, Web báo sai mật khẩu ư? Cùng xem log nhé!

Vậy có nghĩa là [email protected] là không có thật, chúng ta cùng thử cách khác xem sao nhé.

Giờ chúng ta sẽ thử thay password thành "password'"

Và đây là log sau khi chúng ta thêm dấu ' vào.

-Sai limit SQL ư?

Đúng rồi. Vì server sử dụng Input từ biến password trong SQL như thế này:

SELECT * FROM users WHERE username='john' AND password='123456'

Từ đó chúng ta sẽ bị lỗi input vì thừa một dấu " ' "

Vậy giờ chúng ta thử password là: "' or 1=1--"

Từ đó trong code sẽ như thế này:

AND pass = '' or 1=1--' LIMIT 1

Vậy lệnh -- sẽ làm cho máy tính không đọc password, sẽ cho là đúng và user được vào thẳng luôn.

Từ đó, chúng ta đã thấy đây là một lỗi rất lớn của các trang web. 

Thi hành lệnh từ xa bằng SQL Injection (MS SQL)

Nếu cài đặt với chế độ mặc định mà không có điều chỉnh gì, MS SQL Server sẽ chạy ở mức SYSTEM, tương đương với mức truy cập Administrator trên Windows. Có thể dùng store procedure xp_cmdshell trong CSDL master để thi hành lệnh từ xa:

'; exec master..xp_cmdshell 'ping 10.10.1.2'--

Hãy thử dùng dấu nháy đôi (") nếu dấu nháy đơn (') không làm việc.

Dấu chấm phẩy (sẽ kết thúc dòng SQL query hiện tại và cho phép thi hành một SQL command mới. Để kiểm tra xem lệnh trên có được thi hành hay không, có thể listen các ICMP packet từ 10.10.1.2 bằng tcpdump như sau:

#tcpdump icmp

Nếu nhận được ping request từ 10.10.1.2 nghĩa là lệnh đã được thi hành.

Các cách để phòng tránh một cuộc tấn công SQLi

Cách 1: Sử dụng các lệnh tham số

Bước 1: Bạn bắt đầu bằng cách tạo ra một SqlCommand object và sử dụng placeholder @parameter_name trong chuỗi lệnh nơi mà dữ liệu người dùng nhập vào nên được chèn vào.
Bước 2: Sau đó bạn tạo instance của các SqlParameter object, trong đó bạn chèn input của người dùng, thay vì chèn trực tiếp nó vào chuỗi lệnh.
Bước 3: Cuối cùng, bạn thêm SqlParameter object vào bộ tham số SqlCommand object, nó sẽ thay thế các tham số bằng input được cung cấp.

Từ đó, code sẽ thành như sau: 

SqlCommand cmd = new SqlCommand ("SELECT * FROM users WHERE [email protected] AND [email protected]",con);
SqlParameter username = new SqlParameter(); username.ParameterName = "@username"; username.value = txtUsername.Text; cmd.Parameters.Add(username);
SqlParameter password = new SqlParameter(); password.ParameterName = "@password"; password.value = txtPassword.Text; cmd.Parameters.Add(password);

(trích trong CyStack)

Cách 2: Kiểm tra escape String.

Xác nhận là quá trình đảm bảo dữ liệu người dùng nhập vào là hợp lệ và vô hiệu hóa bất kỳ lệnh độc hại tiềm ẩn nào có thể được nhúng trong chuỗi nhập.

Ví dụ, trong PHP, bạn có thể sử dụng mysql \ _real \ _escape \ _string () để thoát các ký tự có thể thay đổi bản chất của lệnh SQL.
Mã đăng nhập được đề cập trước đó sẽ được thay đổi như sau:

Sửa đổi đơn giản này sẽ bảo vệ mã của bạn khỏi cuộc tấn công SQL Injection bằng cách thêm một ký tự thoát (\) phía trước dấu nháy đơn đã được kẻ tấn công thêm vào.

Tạm kết

Cảm ơn các bạn vì đã đọc! Nếu thấy hay thì đừng quên Vote 5* và share hộ mình nhé!

Trong tương lai sẽ có bài viết chi tiết hơn về cách fix trong MySQL và PostgreSQL. Các bạn nhớ đón xem nhé :))