BASIC TO ADVANCE

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.

Đăng ký nhận tin.

Chúng tôi chỉ gửi tối đa 2 lần trên 1 tháng. Tuyên bố không spam mail!

Vũ Thanh Tài

About author
The best way to learn is to share
Xem tất cả bài đăng

5 Comments

Chỉ có người đang học lập trình mới mắc WHERE 1 =1 thôi. Lập trình viên bao giờ cũng phải kiểm tra Text nhập vào từ form. Nói chung những lập trình viên mà mắc lỗi như này chỉ đáng đi dọn nhà vệ sinh

ánh dương

3 năm trước

ánh dương, vì sao bạn biết những kiến thức này? Vì có những người bạn xem là dọn vệ sinh đã đưa nó lên đây cho bạn đọc, bạn học đấy. Học cách ăn cách nói đi bạn!

Lê Bá Minh

2 năm trước

Mình thấy bạn ánh dương nói quá rồi. trên đời này cái gì cũng phải học mà ! vidu:  bạn xúc cơm vào mồm bạn cũng phải học mà ! nếu không học bạn sẽ xúc vào lỗ đít của bạn đó ! mình nghĩ bạn nên bỏ cái tính coi thường đó đi !

Đào Văn Phước

2 năm trước

Hồi xưa chắc bạn cũng đi dọn nhà vệ sinh, à ko bạn còn xúc cả cứt vào mồm nữa nhỉ =))
Khinh, hạng rẻ rách cứ nghĩ mình siêu nhân rồi đi chê, miệt thị người khác.
お前を馬鹿にしている。

Hoang Vu

2 năm trước

Mình thấy bạn ánh dương nói quá rồi. trên đời này cái gì cũng phải học mà ! vidu:  bạn xúc cơm vào mồm bạn cũng phải học mà ! nếu không học bạn sẽ xúc vào lỗ đít của bạn đó ! mình nghĩ bạn nên bỏ cái tính coi thường đó đi !

Đào Văn Phước

2 năm trước

Bình luận

Captcha