DANH MỤC: PHP OPTIMIZE

Lỗi SQL injection Và cách phòng chống


Bài này chúng ta sẽ tìm hiểu về một lỗi nguy hiểm chết người mà nhiều lập trình viên thường mắc phải (kể cả lâu năm). Đó chính là lỗi Sql Injection.

1,SQL Injection là gì?

- SQL injection là một kỹ thuật cho phép những kẻ tấn công lợi dụng lỗ hổng của việc kiểm tra dữ liệu đầu vào trong các ứng dụng web và các thông báo lỗi của hệ quản trị cơ sở dữ liệu trả về để tiêm vào và thi hành các câu lệnh SQL bất hợp pháp.

- SQL injection có thể cho phép những kẻ tấn công thực hiện các thao tác như một người quản trị web, trên cơ sở dữ liệu của ứng dụng.

-SQL injection thường được biết đến như là một vật trung gian tấn công trên các ứng dụng web có dữ liệu được quản lý bằng các hệ quản trị cơ sở dữ liệu có cấu trúc như SQL ServerMySQLOracle,...

-Tuy nhiên tại thời điểm mình viết bài này thì nó cũng đã giảm hẳn, nhưng vẫn còn. Do gần đây các khái niệm framework đã và đang được sử dụng rất nhiều (Các framework đều đã được test cẩn thận để phòng tránh các lỗi, trong đó có SQL Injection).

2, Ví dụ tấn công.

-Ví dụ bạn có một Form đăng nhập như sau.

lỗi sql injection

-Và đoạn code server xử lý của bạn:

if(isset($_POST['username']) && isset($_POST['password'])){
	$sql = "SELECT * FROM tbl_user WHERE username='". $_POST['username'] . "' AND password = '" .$_POST['password'] ."'";
}

-Đoạn code trên vẫn hoạt động bình thường, nhưng nếu như người dùng không nhập bình thường nữa mà chẳng hạn như họ có thêm một dấu nháy ' hoặc " vào thì đương nhiên dòng code của bạn sẽ bị lỗi ngay.

-Hoặc họ có thể sửa thành một câu truy vấn luôn luôn đúng như sau.

SELECT * FROM tbl_user WHERE username = '' OR '1' = '1' and password = '' OR '1' = '1'

-Và nó sẽ còn tệ hại hơn khi mà người dùng chèn thêm một câu lệnh truy vấn phía sau:

VD:

SELECT * FROM tbl_user WHERE username = 'admin' and password = 'admin'; Drop table users;

-Các bạn nhìn vào thì đủ biết chuyện gì sẽ xảy ra đúng không nào.

3, Cách phòng chống.

-Cách phòng trống đối với dạng này thì cũng khá đơn giản. Các bạn chỉ cần ràng buộc thật kỹ dữ liệu người dùng nhập vào và luôn luôn phải có quan điểm 'Đừng bao giờ tin vào những thứ người dùng nhập vào là đúng'.

Luôn ràng buộc kiểu dữ liệu

-Trong ứng dụng thì bạn luôn phải nhớ ràng buộc dữ liệu thật cẩn thận.

VD: Như đối với phương thức get url: http://domain.com?id=5.

//Thông thường
$id = $_GET['id'];
//Ràng buộc cẩn thận
$id = isset($_GET['id'])?(string)(int)$_GET['id']:false;

Regular Expression

-Hoặc bạn có thể dùng Regular Expression để loại bỏ đi các ký tự lạ hoặc các ký tự không phải là số.

VD:

$id = isset($_GET['id']) ? $_GET['id'] : false;
$id = str_replace('/[^0-9]/', '', $id);

Dùng các hàm có sẵn để giảm thiểu lỗi.

-Mỗi khi truy vấn thì mọi người nên sử dụng thêm hàm mysqli_real_escape_string để chuyển đổi một chuỗi thành một query an toàn.

VD:

$id = isset($_GET['id'])?(string)(int)$_GET['id']:false;
$sql= 'SELECT * FROM tbl_user WHERE id= ' . mysqli_real_escape_string($id);

3, Lời Kết.

-Như vậy mình đã giới thiệu được với mọi người về lỗi SQL injection và một số cách phòng tránh cơ bản, tuy nhiên để đảm bảo tránh được 100% các lỗi liên quan đến SQL injection thì mình khuyên mọi người nên sử dụng các framework thay vì code thuần.

Nguồn: Toidicode.com

Thông tin tác giả

Vũ Thanh Tài

Vũ Thanh Tài

The best way to learn is to share

Hãy tham gia group facebook để cùng giao lưu chia sẻ kiến thức! Tham Gia