SQL Injection là gì
💻 SQL Injection là kỹ thuật cho phép hacker lợi dụng các lỗ hổng trong việc kiểm tra điều kiện dựa vào dữ liệu đầu vào (thường do người dùng nhập từ UI) hoặc khi thực thi các câu lệnh truy vấn và các thao tác khác trong hệ quản trị cơ sở dữ liệu (Database Management System – DBMS) để truy cập dữ liệu bất hợp pháp.
Nếu bạn đã từng học môn Quản Trị Cơ Sở Dữ Liệu thì bạn sẽ biết rằng một số DBMS như SQL Server, Oracle, DB2, mongoDB, v.v. sẽ kiểm tra “quyền của bạn” qua mệnh đề WHERE hay HAVING. Tuy mọi truy vấn này đều dựa vào điều kiện nhất định, nhưng bằng cách nào đó hacker sẽ “vượt qua” (by pass) được bước kiểm tra này để truy vấn dữ liệu ngay khi họ không có quyền làm điều đó.
Cơ chế tấn công SQL injection
Xin nhắc lại, để tìm hiểu về SQL injection, trước hết tester cần hiểu cơ chế tấn công SQL Injection và khái niệm SQL injection.
Trong quá trình xây dựng ứng dụng phần mềm (cả ứng dụng web và ứng dụng chạy trực tiếp trên hệ điều hành Windows hay MacOS – thường gọi là “Desktop application”) có thể gặp một số thiếu sót liên quan đến việc xử lý dữ liệu do người dùng nhập vào từ UI. Hacker thường sử dụng những lỗi này để thực hiện các câu truy vấn SQL bất hợp pháp nhằm tấn công vào hệ thống ứng dụng phần mềm của chúng ta để khai thác dữ liệu trái phép.
Để hiểu về kỹ thuật SQL Injection này đòi hỏi bạn phải biết thao tác với SQL, ít nhất là với 1 loại DB nào đó. Tester biết SQL là một lợi thế vì bạn có thể test về khía cạnh kiểm thử bảo mật (security testing) này.
Như đã nói ở trên, bạn cần phải hiểu SQL là gì thì bạn mới có thể đi tiếp được. Nếu chưa biết về SQL bạn có thể tự học SQL thông qua nhiều trang online và tài liệu trên mạng hoặc tham khảo khóa học SQL dành cho tester ở đây (khóa học SQL cơ bản dành cho Testers được thiết kế gói gọn trong 9 tiếng thực hành trên máy.
Vui lòng tham khảo thông tin chi tiết nội dung khóa học SQL for Testers ở đây.
Một số lỗi SQL Injection thường gặp
Để hiểu hơn về các lỗi SQL Injection có thể xảy ra, chúng ta xem qua một số ví dụ sau đây. Nên nhớ rằng, dưới đây là 4 lỗi cơ bản thường gặp, ngoài ra có rất nhiều cách để tấn công SQL injection.
👀 Quên kiểm tra ký tự kết thúc truy vấn
SQL Injection xảy ra khi thiếu đoạn mã kiểm tra dữ liệu đầu vào trong câu truy vấn SQL. Kết quả là người dùng cuối có thể thực hiện 1 số truy vấn không mong muốn với Cơ sở dữ liệu (CSDL):
SELECT * FROM users WHERE name = ' {userName} ' ;
Câu lệnh trên thực hiện truy vấn thuộc tính name từ bảng users. Tuy nhiên, nếu biến “userName” được nhập chính xác theo một cách nào đó thì người dùng ác ý (ví dụ hacker) có thể nhập vào giá trị của biến userName = a’ OR ‘t’ = ‘t thì khi chương trình thực thi câu lệnh ở trên sẽ trở thành:
SELECT * FROM users WHERE name = 'a' OR 't' = 't';
Đoạn mã trên được sử dụng để xác thực thì ví dụ trên có thể được sử dụng để bắt buộc lựa chọn tên người dùng hợp lệ bởi ‘t’ = ‘t’ luôn đúng.
Trong khi hầu hết các SQL server cho phép thực hiện nhiều truy vấn cùng lúc chỉ với một lần gọi, thì một số hệ quản trị cơ sở dữ liệu như mysql_query của PHP lại không cho phép làm điều đó vì lý do bảo mật. Điều này chỉ ngăn cản tin tặc tấn công bằng những câu lệnh riêng rẽ mà không ngăn cản tin tặc tấn công bằng việc thay đổi cú pháp truy vấn.
Ví dụ trên cho thấy giá trị của biến userName (do người dùng nhập vào từ UI) sẽ gây ra việc xóa thông tin người dùng từ bảng users cũng tương tự việc xóa tất cả dữ liệu từ bảng dữ liệu (bản chất là thực hiện hành động không được phép). Minh hoạ cụ thể bằng câu truy vấn dưới đây để hiểu rõ được bản chất hơn:
DROP TABLE users; SELECT * FROM data WHERE 't' = 't'
Như vậy, tin tặc lợi dụng những lỗ hổng (sơ hở) trong cú pháp truy vấn SQL để xâm nhập trái phép dữ liệu trong hệ thống của chúng ta một cách dễ dàng.
🌱Xử lý không đúng kiểu dữ liệu
Trong quá trình lập trình, lập trình viên (developer) không định nghĩa dữ liệu đầu vào của các biến một cách rõ ràng, hoặc thiếu bước kiểm tra sàng lọc kiểu dữ liệu đầu vào, ví dụ kiểm tra (validate) dữ liệu do người dùng nhập vào từ UI là kiểu số (Number), chuỗi (String), hay kiểu ngày tháng (Date).
Xem xét câu truy vấn này
SELECT * FROM data WHERE id = {variable} ;
Câu truy vấn trên không mô tả rõ ràng biến “id” sẽ chấp nhận kiểu dữ liệu dạng số hay chuỗi. Thay vì nhập kiểu số, người dùng nhập một chuỗi nhiều ký tự thì chuyện gì sẽ xảy ra? Đây cũng là một trong những lỗ hổng giúp tin tặc tấn công cơ sở dữ liệu dễ dàng hơn.
☘️Lỗi bảo mật bên trong máy chủ vận hành cơ sở dữ liệu (CSDL)
Đôi khi lỗ hổng bảo mật nằm ngay trong chính máy chủ CSDL. Hacker có thể tấn công SQL injection bằng cách dựa vào hàm mysql_real_escape_string(), họ sử dụng/đưa vào các ký tự unicode bất thường thông thường, xem một số ví dụ sau:
$user ="<div> user </div>
$password = "<div> password</div>
$query = sprintf( "SELECT * FROM users WHERE username ='%s' AND password = '%s'")
mysql_real_escape_string($user)
mysql_real_escape_string($password)
echo $query;
Kết quả in ra sẽ là:
SELECT * FROM users WHERE user = ' ' AND password = ' '
Tiếp đến 1 trường hợp nữa, tại form đăng nhập, người dùng nhập tên đăng nhập mà không cần đúng mật khẩu
<?php
$query = "SELECT * FROM users
WHERE username = '{$_POST['username']}' AND password = '{$_POST['password']}'";
mysql_query($query);
$_POST['username'] = ' your's name';
$_POST['password'] = " OR "=";
echo $query;
?>
Câu lệnh truyền lên server sẽ là:
SELECT * FROM users WHERE username = 'your' AND password = " OR "="
🍀 Blind SQL injection
Lỗi SQL injection dạng Blind SQL injection xảy ra ngay trong ứng dụng web. Kết quả của cách tấn công này không mang lại kết quả ngay tức thời cho người thực hiện (ví dụ hacker) mà nó làm cho dữ liệu của hệ thống chúng ta bị trở nên “vô hiệu” hoặc bị lỗi. Dữ liệu lỗi này gây ra nhiều sự cố khác trong hệ thống nếu như chương trình của bạn không xử lý tốt các trường hợp invalid data (dữ liệu không hợp lệ).
Thứ nhất, người dùng hoặc/và khách hàng của bạn sẽ gặp nhiều khó khăn vì không đăng nhập vào hệ thống được, hoặc dữ liệu của họ hoàn toàn bị trở nên không sử dụng được.
Thứ hai, nhóm phát triển phần mềm của bạn sẽ phải vất vả để khôi phục lại sự hoạt động/vận hành trơn tru của hệ thống. Nếu có cơ chế lưu trữ tốt, mọi thứ sẽ dễ dàng hơn. Ngược lại, có thể không khôi phục được hiện trạng dữ liệu ban đầu.
Thứ ba, những kẻ tấn công sẽ sử dụng nhiều công cụ khác để dò các thông báo lỗi từ hệ thống của bạn, từ đó họ xây dựng ra bức tranh tổng thể về công nghệ và cách thức vận hành đằng sau, kể cả phiên bản của thư viện hiện tại như .net framework 4.5, và họ sẽ đưa ra chiến lược tấn công hệ thống của bạn từ những thông tin cực kỳ hữu ích này.
🎉🎉🎉
Trên đây là một số lỗi SQL Injection cơ bản, ngoài ra còn rất nhiều các dạng tấn công khác xảy ra khi mà hacker sử dụng kỹ thuật SQL injection và lỗi sơ hở trong các câu truy vấn để đột nhập lấy cắp dữ liệu. Tuy nhiên, không phải hệ thống nào cũng dễ dàng bị tấn công bởi các ví dụ trên đây nhưng khi hiểu biết thêm về vấn đề này giúp tester thiết kế bộ test case hiệu quả hơn.
Ngày nay với sự phát triển liên tục của công nghệ thì các trình duyệt và thư viện lập trình đã xử lý tốt hầu hết những lỗi cơ bản. Nhưng điều này không bảo đảm hệ thống phần mềm của bạn sẽ không bị tấn công bởi kỹ thuật này.
Một số câu hỏi liên quan đến SQL Injection
Nếu có câu hỏi khác, các bạn vui lòng để lại bên dưới phần bình luận nhé.
Thời điểm thực hiện kiểm tra SQL injection càng sớm càng tốt, thậm chí ngay thời điểm “review code” – cần xem kỹ phần mã nguồn liên quan đến việc xử lý các câu lệnh truy vấn. Và sau đó tester cũng nên thực hiện kiểm thử các trường hợp liên quan đến SQL injection trong lúc kiểm thử hệ thống từ UI.
Tuỳ vào thời điểm mà người phù hợp để thực hiện kiểm thử liên quan đến khía cạnh này có thể bao gồm tester, developer, hoặc chuyên viên kiểm thử bảo mật – penetration testers.
Cám ơn bạn đã đọc hết bài viết và chúc bạn kiểm thử hiệu quả.
Nguồn tham khảo: https://www.testingvn.com/viewtopic.php?t=91290