SQL Injection là gì? SQL Injection là một kỹ thuật chèn code được sử dụng trong tấn công các ứng dụng chứa dữ liệu (data-driven). Trong đó, các lệnh SQL độc hại được chèn vào trong một entry field để thực thi (chẳng hạn như để kết xuất nội dung Cơ sở dữ liệu cho hacker). SQL Injection phải khai thác lỗ hổng bảo mật trong phần mềm của ứng dụng. SQL Injection chủ yếu được biết đến như một vector tấn công dành cho các trang web. Nhưng nó cũng có thể được dùng để tấn công bất kỳ loại cơ sở dữ liệu SQL nào. Các cuộc tấn công SQL Injection cho phép hacker giả mạo danh tính, xáo trộn dữ liệu. Hay gây ra các vấn đề như làm mất hiệu lực giao dịch, thay đổi số dư, tiết lộ hay phá hủy dữ liệu trên hệ thống. Thậm chí là làm dữ liệu không khả dụng hoặc trở thành admin của server cơ sở dữ liệu. Các loại SQL Injection SQL Injection có ba loại: In-band SQLi (Classic), Inferential SQLi (Blind) và Out-of-band SQLi. Bạn có thể phân loại các kiểu SQL injection dựa trên phương pháp sử dụng để truy cập dữ liệu backend, hoặc khả năng gây hại của chúng. In-band SQLi Kẻ tấn công sử dụng cùng một kênh liên lạc để khởi động các cuộc tấn công và thu thập các kết quả. Tính đơn giản và hiệu quả của In-band SQLi khiến nó trở thành một trong những kiểu tấn công SQLi phổ biến nhất hiện nay. Có hai biến thể phụ của phương pháp này: - Error-based SQLi – Hacker sẽ thực hiện các hành động làm cơ sở dữ liệu tạo ra thông báo lỗi. Hacker có thể dùng dữ liệu được cung cấp bởi các thông báo lỗi này để thu thập thông tin về cấu trúc của cơ sở dữ liệu.
- Union-based SQLi – Kỹ thuật này lợi dụng toán tử UNION SQL để kết hợp nhiều câu lệnh được tạo bởi Cơ sở dữ liệu để nhận được một HTTP response. Response này có thể chứa dữ liệu mà kẻ tấn công có thể sử dụng.
>>> Xem thêm: mua máy chủ sr850
Inferential (Blind) SQLi Hacker sẽ gửi các data payload đến server và quan sát phản ứng, hành vi của server để tìm hiểu về cấu trúc của nó. Phương pháp này được gọi là Blind SQLi vì dữ liệu không được chuyển từ Cơ sở dữ liệu trang web đến hacker. Do đó hacker không thể nhìn thấy thông tin về cuộc tấn trong in-band. Blind SQL injection dựa trên phản ứng và các hành vi hoạt động của server. Do đó chúng thường thực thi chậm hơn, nhưng có thể gây ảnh hưởng tương tự. Blind SQL injection có thể được phân loại thành: - Boolean – Hacker gửi một truy vấn SQL đến Cơ sở dữ liệu, làm ứng dụng trả về một kết quả. Kết quả có thể khác nhau tùy vào truy vấn đúng hay sai. Dựa trên kết quả, thông tin trong HTTP response sẽ sửa đổi hoặc không. Sau đó, hacker có thể tìm hiểu xem thông báo tạo ra kết quả có đúng không.
- Time-based – Hacker sẽ gửi một truy vấn SQL đến Cơ sở dữ liệu, làm cho Cơ sở dữ liệu đợi (trong vài giây) trước khi có thể hoạt động. Sau đó, hacker có thể xem từ thời gian Cơ sở dữ liệu cần để phản hồi, một truy vấn là đúng hay sai. Dựa trên kết quả, một HTTP repsonse sẽ được tạo ra. Vì vậy hacker có thể tìm ra thông báo mà chúng đã sử dụng trả về đúng hay sai, không cần dựa vào dữ liệu từ Cơ sở dữ liệu.
Out-of-band SQLi Hacker chỉ có thể thực hiện hình thức này khi có một số tính năng nhất định được kích hoạt trên server Cơ sở dữ liệu được ứng dụng web sử dụng. Hình thức này chủ yếu được dùng để thay thế cho khác kỹ thuật in-band và inferential SQLi. Out-of-band SQLi được thực hiện khi hacker không thể sử dụng cùng một kênh để khởi động tấn công và thu thập thông tin. Hoặc do server quá chậm, không ổn định tấn thực hiện hành động. Các kỹ thuật này dựa vào khả năng server tạo ra các DNS hay HTTP request để chuyển dữ liệu cho kẻ tấn công. Ví dụ về cách sử dụng SQL Injection Kẻ tấn công muốn thực hiện SQL injection sẽ thao túng một truy vấn SQL tiêu chuẩn, để khai thác các lỗ hổng input không được xác thực trong Cơ sở dữ liệu. Có nhiều cách để thực hiện vector tấn công này. Sau đây là một số cách để vận hành SQLi: Lấy ví dụ về input ở trên. Nó sẽ lấy thông tin cho một sản phẩm cụ thể, có thể được đổi thành Bash Vì lệnh 1=1 là luôn đúng, nên truy vấn trả về tất cả tên và mô tả sản phẩm trong Cơ sở dữ liệu, ngay cả những tên mà bạn không đủ điều kiện truy cập. Những hacker cũng có thể lợi dụng các ký tự được lọc không chính xác để thay đổi các lệnh SQL. Trong đó gồm cả việc sử dụng dấu chấm phẩy để tách hai trường. Bash Lúc đó, toàn bộ Cơ sở dữ liệu có thể bị xóa. Một cách khác để thao túng truy vấn SQL là sử dụng lệnh UNION SELECT. Nó kết hợp hai truy vấn SELECT không liên quan để lấy dữ liệu từ các bảng Cơ sở dữ liệu khác nhau. Bash Bằng cách sử dụng lệnh UNION SELECT, truy vấn này kết hợp request cho tên và mô tả mục item 999 với một request khác, pull tên và password cho mọi người dùng trong Cơ sở dữ liệu. >>> Xem thêm: sr650 máy chủ
Cách ngăn chặn SQL Injection Chúng ta cần biết được cách phòng chống SQL injection hiệu quả. Vì SQL Injection có vector chính là các kênh input của người dùng. Nên cách tiếp cận tốt nhất là kiểm soát và xem xét input của người dùng để theo dõi các kiểu tấn công. Các developer cũng có thể tránh các lỗ hổng bảo mật bằng cách áp dụng các cách phòng chống SQL injection sau: Input Validation (Xác thực đầu vào) Quá trình xác thực nhằm xác minh xem loại input do người dùng gửi có hợp lệ hay không. Xác thực đầu vào đảm bảo đó là kiểu, độ dài, định dạng… được chấp nhận. Chỉ các giá trị qua được xác thực mới có thể được xử lý. Nó giúp chống lại mọi lệnh được chèn vào trong chuỗi input. Xác thực nên được áp dụng với các trường cho phép người dùng nhập đầu vào, mà bạn còn nên quan tâm đến các tình huống sau: - Sử dụng biểu thức chính quy làm whitelist cho các dữ liệu có cấu trúc (chẳng hạn như tên, tuổi, thu nhập, zip code) để đảm bảo xác thực đầu vào hợp lệ.
- Trong trường hợp có một bộ giá trị cố định (như drop-down list), hãy xác định giá trị được trả về. Dữ liệu đầu vào phải khớp với một trong các tùy chọn được cung cấp.
Dưới đây là cách xác thực tên bảng: switswitch ($tableName) { case 'fooTable': return true; case 'barTable': return true; default: return new BadMessageException('unexpected value provided as table name'); } PHP Biến $tableName có thể được append trực tiếp, bây giờ nó được biết đến là một trong những giá trị hợp pháp cho tên của Table. Stored Procedures Các stored procedures (SP) yêu cầu developer nhóm một hay nhiều lệnh SQL thành một đơn vị logic để có thể tạo một kế hoạch thực thi. Các lần thực thi tiếp theo cho phép các lệnh được tham số hóa tự động. Nói một cách đơn giản, nó là một loại code có thể được lưu trữ để sử dụng sau này. Vì vậy, bất cứ khi nào bạn cần thực hiện truy vấn, thay vì viết đi viết lại thì có thể gọi một stored procedure. Đây là một quá trình tạo một SP trong server MySQL. Ví dụ bạn có một bảng như sau: CREATE TABLE `salary` ( `empid` int(11) NOT NULL, `sal` int(11) DEFAULT NULL, PRIMARY KEY (`empid`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; Bash Giả sử có một nhân viên cần lấy dữ liệu tổng hợp về lương công ty từ Table đó. Trước tiên, bạn cần tạo một người dùng ‘tr’: CREATE USER 'tr'@'localhost' IDENTIFIED BY 'mypass'; Bash Người dùng đó sẽ chỉ cần quyền EXECUTE đối với lược đồ nơi có Table: grant execute on hris.* to tr@`%` Bash SP sẽ được tạo như sau: DELIMITER $$ CREATE PROCEDURE `avg_sal`(out avg_sal decimal) BEGIN select avg(sal) into avg_sal from salary; END Bash Quá trình phát hành lệnh tạo một avg_sal SP và nó sẽ được lưu trữ trong Cơ sở dữ liệu. Để gọi một SP từ một ừng dụng PHP, bạn có thể sử dụng PDO: $db_connection = new PDO('mysql:host=localhost;dbname=hris', 'tr', 'mypass'); $query = $db_connection->exec('call avg_sal(@out)'); $res = $query->query('select @out')->fetchAll(); print_r($res); Bash $res sẽ hiện thị mức lương trung bình theo yêu cầu người dùng. Sau đó, người dùng có thể thực hiện quá trình output với PHP. >>> Xem thêm: mua máy chủ lenovo sr550
|