SQL Injection là gì? Tìm hiểu về 3 loại SQL Injection

SQL Injection là gì?

SQL InjectionSQL Injection là gì?
SQL Injection là một kỹ thuật chèn code được sử dụng trong tiến công những ứng dụng chứa tài liệu ( data-driven ). Trong đó, những lệnh SQL ô nhiễm được chèn vào trong một entry field để thực thi ( ví dụ điển hình như để kết xuất nội dung Cơ sở tài liệu cho hacker ). SQL Injection phải khai thác lỗ hổng bảo mật thông tin trong ứng dụng của ứng dụng .
SQL Injection hầu hết được biết đến như một vector tiến công dành cho những website. Nhưng nó cũng hoàn toàn có thể được dùng để tiến công bất kể loại cơ sở tài liệu SQL nào. Các cuộc tiến công SQL Injection được cho phép hacker giả mạo danh tính, trộn lẫn tài liệu. Hay gây ra những yếu tố như làm mất hiệu lực thực thi hiện hành thanh toán giao dịch, đổi khác số dư, bật mý hay hủy hoại tài liệu trên mạng lưới 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ở tài liệu .

>> Xem thêm: Thẻ Input trong HTML là gì? Tổng hợp các ví dụ cụ thể

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ẻ tiến công sử dụng cùng một kênh liên lạc để khởi động những cuộc tiến công và tích lũy những tác dụng. Tính đơn thuần và hiệu suất cao của In-band SQLi khiến nó trở thành một trong những kiểu tiến công SQLi phổ cập nhất lúc bấy giờ. Có hai biến thể phụ của giải 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.

Inferential (Blind) SQLi

tin tặc sẽ gửi những data payload đến server và quan sát phản ứng, hành vi của server để khám phá về cấu trúc của nó. Phương pháp này được gọi là Blind SQLi vì tài liệu không được chuyển từ Cơ sở tài liệu website đến hacker. Do đó hacker không hề 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à những hành vi hoạt động giải trí của server. Do đó chúng thường thực thi chậm hơn, nhưng hoàn toàn có thể gây ảnh hưởng tác động tương tự như. Blind SQL injection hoàn toàn 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

tin tặc chỉ hoàn toàn có thể thực thi hình thức này khi có một số ít tính năng nhất định được kích hoạt trên server Cơ sở tài liệu được ứng dụng web sử dụng. Hình thức này hầu hết được dùng để sửa chữa thay thế cho khác kỹ thuật in-band và inferential SQLi .
Out-of-band SQLi được thực thi khi hacker không hề sử dụng cùng một kênh để khởi động tiến công và tích lũy thông tin. Hoặc do server quá chậm, không không thay đổi tấn thực thi hành vi. Các kỹ thuật này dựa vào năng lực server tạo ra những DNS hay HTTP request để chuyển tài liệu cho kẻ tiến công .

Ví dụ về cách sử dụng SQL Injection

Kẻ tiến công muốn triển khai SQL injection sẽ thao túng một truy vấn SQL tiêu chuẩn, để khai thác những lỗ hổng input không được xác nhận trong Cơ sở tài liệu. Có nhiều cách để triển khai vector tiến công này. Sau đây là 1 số ít cách để quản lý và vận hành SQLi :
Lấy ví dụ về input ở trên. Nó sẽ lấy thông tin cho một loại sản phẩm đơn cử, hoàn toàn có thể được đổi thành

http://www.estore.com/items/items.asp?itemid=999 or 1=1

Và truy vấn SQL sẽ có dạng như sau :

Vì lệnh 1 = 1 là luôn đúng, nên truy vấn trả về tổng thể tên và miêu tả loại sản phẩm trong Cơ sở tài liệu, ngay cả những tên mà bạn không đủ điều kiện kèm theo truy vấn .
Những hacker cũng hoàn toàn có thể tận dụng những ký tự được lọc không đúng chuẩn để biến hóa những lệnh SQL. Trong đó gồm cả việc sử dụng dấu chấm phẩy để tách hai trường .
Ví dụ, có input :

http://www.estore.com/items/iteams.asp?itemid=999; DROP TABLE USERS

Người dùng sẽ tạo truy vấn SQL như sau :

Lúc đó, hàng loạt Cơ sở tài liệu hoàn toàn 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.

Ví dụ, có input:

http://www.estore.com/items/items.asp?itemid=999 UNION SELECT user-name, password FROM USERS

Input này sẽ tạo truy vấn SQL sau :

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.

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 suất cao. Vì SQL Injection có vector chính là những kênh input của người dùng. Nên cách tiếp cận tốt nhất là trấn áp và xem xét input của người dùng để theo dõi những kiểu tiến công. Các developer cũng hoàn toàn có thể tránh những lỗ hổng bảo mật thông tin bằng cách vận dụng những cách phòng chống SQL injection sau :

Input Validation (Xác thực đầu vào)

Quá trình xác nhận nhằm mục đích xác định 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 bảo vệ đó là kiểu, độ dài, định dạng … được đồng ý. Chỉ những giá trị qua được xác nhận mới hoàn toàn có thể được giải quyết và 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 nhận tên bảng :

switswitch ($tableName) {
    case 'fooTable': return true;
    case 'barTable': return true;
    default: return new BadMessageException('unexpected value provided as table name');
}

Biến USD tableName hoàn toàn có thể được append trực tiếp, giờ đây nó được biết đến là một trong những giá trị hợp pháp cho tên của Table .
Đối với drop-down list, việc xác nhận tài liệu rất đơn thuần. Giả sử bạn muốn người dùng chọn xếp hạng từ 1 đến 5, hãy đổi PHP code thành :

 0) && ($number < 6))
    {
        echo "Selected rating: ". $number;
    }
    else
        echo "The rating has to be a number between 1 and 5!";
}

Bạn đã thêm hai check đơn thuần :

  1. Phải là một số (hàm is_numeric())
  2. $number phải lớn hơn 0, nhỏ hơn 6. Do đó điểm có phạm vi từ 1 – 5.

Dữ liệu nhận được từ bên ngoài phải được xác nhận. Quy tắc này không chỉ vận dụng cho input do người dùng Internet cung ứng, mà còn cho những nhà sản xuất, đối tác chiến lược, cơ quan quản trị .

Parametrized queries (Tham số hóa truy vấn)

Các truy vấn tham số hóa là một phương tiện đi lại pre-compile lệnh SQL. Sau đó bạn hoàn toàn có thể cung ứng những tham số để câu lệnh được thực thi .
Phương pháp này giúp Cơ sở tài liệu hoàn toàn có thể nhận ra mã và phân biệt nó với tài liệu nguồn vào .
Input của người dùng được trích dẫn tự động hóa, và kiểu mã hóa này giúp giảm thiểu tiến công SQL injection .
Ta cũng hoàn toàn có thể sử dụng những truy vấn tham số hóa với phần lan rộng ra MySQLi, nhưng PHP 5.1 đã trình diễn một cách tiếp cận tốt hơn khi thao tác với CSDL : PHP Data Objects ( PDO ). PDO vận dụng những chiêu thức đơn giản hóa việc sử dụng những truy vấn tham số hóa. Ngoài ra, nó làm cho code dễ đọc hơn và dễ vận động và di chuyển hơn, vì nó còn hoạt động giải trí trên 1 số ít Cơ sở tài liệu khác, không riêng gì mỗi MySQL .
Code này sử dụng PDO với những truy vấn được tham số hóa để ngăn ngừa lỗ hổng SQL injection :

prepare($sql);
$query->bindParam(':id', $id);
$query->execute();
//getting the result
$query->setFetchMode(PDO::FETCH_ASSOC);
$result = $query->fetchColumn();
print(htmlentities($result));

Stored Procedures

Các stored procedures ( SP ) nhu yếu developer nhóm một hay nhiều lệnh SQL thành một đơn vị chức năng logic để hoàn toàn có thể tạo một kế hoạch thực thi. Các lần thực thi tiếp theo được cho phép những lệnh được tham số hóa tự động hóa. Nói một cách đơn thuần, nó là một loại code hoàn toàn có thể được tàng trữ để sử dụng sau này .
Vì vậy, bất kể khi nào bạn cần triển khai truy vấn, thay vì viết đi viết lại thì hoàn toàn có thể gọi một stored procedure .
Đây là một quy 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;

Giả sử có một nhân viên cấp dưới cần lấy tài 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';

Người dùng đó sẽ chỉ cần quyền EXECUTE so với lược đồ nơi có Table :

grant execute on hris.*  to tr@`%`

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

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 hoàn toà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);

USD res sẽ hiện thị mức lương trung bình theo nhu yếu người dùng. Sau đó, người dùng hoàn toàn có thể thực thi quy trình output với PHP .

Sử dụng Escaping

Luôn sử dụng các hàm character-escaping cho input do user cung cấp, được cấp bởi mỗi hệ thống quản lý Cơ sở dữ liệu (DBMS). Việc này giúp đảm bảo DBMS không bao giờ nhầm lẫn nó với lệnh SQL do developer cung cấp.

Ví dụ: dùng mysql_real_escape_string() trong PHP để tránh các ký tự có thể dẫn đến lệnh SQL không mong muốn. Một phiên sửa đổi cho login bypass sẽ như sau:

$db_connection = mysqli_connect("localhost", "user", "password", "db");
		$username = mysqli_real_escape_string($db_connection, $_POST['username']);
		$password = mysqli_real_escape_string($db_connection, $_POST['password']);
		$query = "SELECT * FROM users WHERE username = '". $username. "' AND password = '". $password. "'"; 

Trước đây, code của bạn hoàn toàn có thể dễ bị thêm escape character ( \ ) ở phía trước dấu ngoặc. Tuy nhiên, bằng mã trên bạn sẽ được bảo vệ khỏi người dùng phạm pháp và giảm thiểu SQL injection .

Lời kết

Vietnix vừa san sẻ cho bạn về những loại SQL Injection và những cách phòng chống yếu tố này, kỳ vọng qua bài viết này bạn sẽ học thêm được nhiều kỹ năng và kiến thức mới và biết cách ngăn chăn SQL Injection hiệu suất cao, chúc bạn thành công xuất sắc !