Thứ Sáu, 20 tháng 10, 2017

SQL Injection - Khanhdv

1. SQL Injection là gì?
SQL Injection là một trong những kiểu hack web đang dần trở nên phổ biến hiện nay. Bằng cách inject các mã SQL query/command vào input trước khi chuyển cho ứng dụng web xử lí, bạn có thể login mà không cần username và password, remote execution, dump data và lấy root của SQL server. Công cụ dùng để tấn công là một trình duyệt web bất kì, chẳng hạn như Internet Explorer, Netscape, Lynx, ...

Tại sao SQL Injection lại “thần thánh”?

Những lý do sau đã tạo nên tên tuổi lừng lẫy của SQL Injection:
• Cực kỳ nguy hiểm – Có thể gây ra những thiệt hại khổng lồ. Với SQL Injection, hacker có thể truy cập một phần hoặc toàn bộ dữ liệu trong hệ thống.
• Rất phổ biến và dễ thực hiện – Lỗ hổng này rất nổi tiếng, từ developer đến hacker gần như ai cũng biết. Ngoài ra, còn có 1 số tool tấn công SQL Injection cho dân “ngoại đạo”, những người không biết gì về lập trình.
• Rất nhiều ông lớn từng bị dính – Sony, Microsoft UK. Mọi vụ lùm xùm liên quan tới “lộ dữ liệu người dùng” ít nhiều đều dính dáng tới SQL Injection

MỘT SỐ VÍ DỤ
1. TẤN CÔNG BẰNG MỆNH ĐỀ LUÔN ĐÚNG
Những lỗi lập trình này thường xảy ra ở các chức năng tìm kiếm hoặc đăng nhập tài khoản. Ví dụ một câu lệnh SQL như sau:
SELECT * FROM accounts WHERE userName = '{$userName}'
Đây có lẽ là một câu lệnh quen thuộc đối với mỗi dân code trong chúng ta. Tiếp theo mình sẽ chỉ cho các bạn thấy đoạn SQL trên có rủi ro như thế nào nhé. Giả sử trong ô đăng nhập người dùng nhập thêm đằng sau là
or '1' = '1'
 thì khi truy vấn, câu lệnh của chúng ta sẽ trở thành mệnh đề luôn đúng như dưới đây: 
SELECT * FROM accounts WHERE userName = '{$userName}' OR '1' = '1'
Vì là luôn đúng, nên câu lệnh trên luôn thực thi và trả về kết quả khiến hacker cùi bắp có thể dễ dàng đăng nhập vào hệ thống của bạn một cách dễ dàng, và điều này là hết sức nguy hiểm, nhất là các trang quản trị toàn bộ nội dung hệ thống như backend vậy. Lần đầu tiên khi mình lập trình web một trang kết bạn cùi bắp cũng bị lỗi này và bị hack mất bao nhiêu là tài khoản.
2. TẤN CÔNG PHÁ HOẠI TRỰC TIẾP DỮ LIỆU
Giả sử câu lệnh cũng như trên, nhưng không nhập ‘1’ = ‘1’ nữa mà thêm như sau:

SELECT * FROM accounts WHERE userName = '{$userName}'; DROP TABLE accounts; ''
SQL hỗ trợ thực hiện nhiều câu lệnh thông qua dấu phân tách là ; nên nếu bị chơi một phát như trên là lập tức bảng accounts của bạn sẽ bị drop sạch dữ liệu mà không thể khôi phục đấy

3. HƯỚNG KHẮC PHỤC
May thay, mặc dù SQL rất nguy hại nhưng cũng dễ phòng chống. Gần đây, hầu như chúng ta ít viết SQL thuần mà toàn sử dụng ORM (Object-Relational Mapping) framework. Các framework web này sẽ tự tạo câu lệnh SQL nên hacker cũng khó tấn công hơn.
Tuy nhiên, có rất nhiều site vẫn sử dụng SQL thuần để truy cập dữ liệu. Đây chính là mồi ngon cho hacker. Để bảo vệ bản thân trước SQL Injection, ta có thể thực hiện các biện pháp sau.
• Lọc dữ liệu từ người dùng: Cách phòng chống này tương tự như XSS. Ta sử dụng filter để lọc các kí tự đặc biệt (; ” ‘) hoặc các từ khoá (SELECT, UNION) do người dùng nhập vào. Nên sử dụng thư viện/function được cung cấp bởi framework. Viết lại từ đầu vừa tốn thời gian vừa dễ sơ sót.
• Không cộng chuỗi để tạo SQL: Sử dụng parameter thay vì cộng chuỗi. Nếu dữ liệu truyền vào không hợp pháp, SQL Engine sẽ tự động báo lỗi, ta không cần dùng code để check.
• Không hiển thị exception, message lỗi: Hacker dựa vào message lỗi để tìm ra cấu trúc database. Khi có lỗi, ta chỉ hiện thông báo lỗi chứ đừng hiển thị đầy đủ thông tin về lỗi, tránh hacker lợi dụng.
• Phân quyền rõ ràng trong DB: Nếu chỉ truy cập dữ liệu từ một số bảng, hãy tạo một account trong DB, gán quyền truy cập cho account đó chứ đừng dùng account root hay sa. Lúc này, dù hacker có inject được sql cũng không thể đọc dữ liệu từ các bảng chính, sửa hay xoá dữ liệu.
• Backup dữ liệu thường xuyên: Các cụ có câu “cẩn tắc vô áy náy”. Dữ liệu phải thường xuyên được backup để nếu có bị hacker xoá thì ta vẫn có thể khôi phục được. Còn nếu cả dữ liệu backup cũng bị xoá luôn thì … chúc mừng bạn, update CV rồi tìm cách chuyển công ty thôi!