kỹ thuật tấn công SQL Injection và cách phòng chống trong php

Ơ bài trước chúng ta đã được tìm hiểu cách phòng chống CSRF, vậy thì trong bài này ta sẽ tìm hiểu thêm một kỹ thuật khác cũng rất hay sử dụng để tấn công vào những website của những tay nghề thiếu kinh nghiệm lập trình, đó là kỹ thuật tấn công SQL Injection.

test php

banquyen png

Bài viết này được đăng tại

freetuts.net

, không được copy dưới mọi hình thức.

1. SQL Injection là gì?

SQL Injection là một kỹ thuật lợi dụng những lỗ hổng về câu truy vấn lấy dữ liệu của những website không an toàn trên web, đây là một kỹ thuật tấn công rất phổ biến và sự thành công của nó cũng tương đối cao. Tuy nhiên vào những năm trở lại đây thì xuất hiện nhiều Framwork nên nó giảm hẳn, vì các FW đã hỗ trợ rất tốt việc chống lại hack SQL Injection này.

Chắc hẳn những bạn đã biết quy mô hoạt động giải trí của website rồi nhỉ ? Khi một request được gửi từ client thì ngôn từ SERVER như PHP sẽ lấy những thông tin từ request đó. Nhưng bản thân nó không hề phát hiện ra những thông tin đó có chứa những câu SQL độc, cho nên vì thế việc làm này ta phải đổ nghĩa vụ và trách nhiệm tới kinh nghiệm tay nghề của lập trình viên .

Ví dụ: Giả sử tôi có một trang đăng nhập với hai thông tin là tên đăng nhậpmật khẩu.

Bài viết này được đăng tại [ không lấy phí tuts. net ]

Đăng nhập tấn công sql injection

Và đoạn code xử lý tấn công sql injection của tôi có dạng như sau:

$username = $_POST['username'];
$password = $_POST['password'];

$sql = "select count(*) from user where username = '$username' AND password = '$password'";

Trường hợp 1: Bây giờ tôi nhập username = thehalfheartpassword = matkhau thì câu truy vấn sẽ là:

Bây giờ tôi nhậpvàthì câu truy vấn sẽ là :

select count(*) from user where username = 'thehalfheart AND password = 'matkhau'

Trường hợp 2: Bây giờ tôi nhập username = somenamepassword = something' OR '1. Như vậy câu sql sẽ là:

SELECT * FROM cms_user WHERE user_username = 'thehalfheart' AND user_password = 'something' OR '1'

Chạy câu truy vấn này lên thì hiệu quả nó trả về là list user nên nếu code cùi cùi thì login được luôn .
Trên đây là một ví dụ nổi bật thôi, chứ thực tiễn thì hacker còn rất nhiều mưu mẹo khác. Tuy nhiên chung quy lại với kỹ thuật tiến công SQL Injection ta vẫn hoàn toàn có thể không chế được nó .

2. Phòng chống SQL Injection

Với kinh nghiệm tay nghề của mình thì thật sự chưa nghiên cứu và phân tích sâu vào kỹ thuật này, tuy nhiên mình cũng biết chút ít kinh nghiệm tay nghề để hoàn toàn có thể chống lại kỹ thuật này .

2.1. Nhận dữ liệu kiểu INT

Khi bạn nhận tài liệu ID trên URL thì cách tốt nhất bạn nên ép kiểu, chuyển nó về kiểu số INT, sau đó chuyển về kiểu STRING ( nếu thiết yếu ) .

Ví dụ: tôi có url như sau: domain.com/detail.php?id=12

$id = isset($_GET['id']) ? (string)(int)$_GET['id'] : false;

Như vậy thì mặc dầu ta nhập vào kỳ tự gì đi nữa đều sẽ bị clear ra khỏi hết. Hoặc ta hoàn toàn có thể dùng cách dước bằng cách dùng hàm preg_replace trong PHP để xóa đi những ký tự không phải là chữ số .

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

2.2 Viết lại đường dẫn có thể chống SQL Injection

Rất đơn thuần, tuy nhiên mình khuyến khích nên dùng ép kiểu trong PHP, vì nó đơn thuần .Vấn đề này có vẻ như hơi lạ nhưng bản thân mình thấy rất đúng. Khi bạn viết lại đường dẫn dù trên mạng lưới hệ thống route của FW hay dù trên file. htaccess thì hãy fix đúng chuẩn đoạn mã Regular Expression ( Tham khảo Regular Expression cơ bản ) .
Ví dụ : Tôi có đường dẫn sau khi rewirte là như sau : domain.com/hoc-lap-trinh-mien-phi-tai-freetuts.html thì đoạn Regex tôi sẽ viết là :

/([a-zA-Z0-9-]+)/([a-zA-Z0-9-]+)\.html/ . Thay vì như vậy thì tôi sẽ viết chính xác  /([a-zA-Z0-9-]+)/([0-9])\.html/ thì sẽ tốt hơn. Và đừng quên là cũng ẩn đi đường link gốc của nó nhé.

2.3 Sử dụng hàm sprintf và mysql_real_escape_string để xác định kiểu dữ liệu cho câu truy vấn.

Như bạn biết hàm sprintf gồm có hai tham số trở lên, tham số thứ nhất là chuỗi và trong đó có chứa một đoạn Regex để thay thế sửa chữa, tham số thứ 2 trở đi là những giá trị sẽ được thay thế sửa chữa tương ứng. Giá trị ráp vào sẽ được convert tương thích rồi mới rap vào
Ví dụ :

$webname = 'freetuts.net';
$title = 'học lập trình miễn phí';
echo sprintf('Website %s laf website %s', $webname, $title);

Website freetuts.net là website học lập trình miễn phí.

Kết quả in ra là :Nếu bạn chưa biết về hàm sprintf thì vào link này đọc nhé .

Như bạn biết hàm mysql_real_escape_string có nhiệm vụ sẽ chuyển một chuỗi thành chuỗi query an toàn, nên ta sẽ kết hợp nó để gán vào câu truy vấn. Ví dụ:

$sql = "SELECT * FROM member WHERE username = '%s' AND password = '%s'";
echo sprintf($sql, mysql_real_escape_string("thehalfheart"), mysql_real_escape_string("matkhau"));

Kết quả là: SELECT * FROM member WHERE username = ‘thehalfheart’ AND password = ‘matkhau’.

SELECT * FROM thành viên WHERE username = ‘ thehalfheart ‘ AND password = ‘ matkhau ‘ .

 

Đang Cập Nhật Thêm …

3. Lời kết

Thật sự thì kỹ thuật này rất nhiều và dài, kiến thức và kỹ năng của mình chỉ mang tầm cơ bản nên mình chỉ share được cơ bản. Nếu bạn muốn nâng cao thì hoàn toàn có thể đọc thêm tài liệu trên mạng, đa phần là tiếng anh. Tuy nhiên thật sự khi đi làm bạn nên sử dụng Framwork, vì FW đa tương hỗ rất tốt những kiểu tiến công website thông dụng lúc bấy giờ rồi, bản thân tất cả chúng ta không thể nào tìm hiểu và khám phá sâu được .