PDA

View Full Version : Cách thức kiểm tra thông tin đăng nhập an toàn trong PHP



vietanh143
19-10-2007, 08:40 PM
Thông thường khi viết một portal hay forum hay là một sản phẩm nào đó có chức năng đăng nhập dành cho thành viên thì đôi khi việc kiểm tra thông tin đăng nhập lại hết sức cần thiết. Nếu nói về những người dùng hợp lệ (tức là đăng nhập bằng chính tài khoản của họ) thì không phải bàn tới, tuy nhiên trong số đó cũng có người ngoại lệ (tức là đăng nhập trái phép)... cách thức họ dùng để đăng nhập trái phép cũng không bàn tới vì sau khi áp dụng bài viết này thì dù họ có trái phép thì ta cũng có thể bắt buộc họ phải đăng nhập một cách hợp lệ.

Trước hết khi kiểm tra thông tin đăng nhập thì yêu cầu có là một form đăng nhập bao gồm: username và password. Và trong đó có 2 trường hợp kiểm tra thông tin đăng nhập:

1. SELECT * FROM users WHERE name='$username' AND password='$password'
2. SELECT * FROM users WHERE name='$username'

Trong trường hợp thứ 1 có thể khẳng định là coder này rất ẩu :d, còn trong trường hợp 2 thì hoàn toàn đúng.

Tại sao trường hợp thứ 1 lại gọi là rất ẩu !? Câu trả lời rất đơn giản, nếu đọc câu lệnh SQL này ra thì có thể đọc là: lấy từ table users nơi có $username và $password - rất có thể sẽ dính by pass ( ' OR '1'='1 ), nếu đăng nhập trái phép theo dạng này thì câu lệnh sẽ trở thành: SELECT * FROM users WHERE name='$username' AND password='' OR '1'='1' - Câu lệnh này cũng sẽ hợp lệ vì cuối cùng khai báo là OR '1'='1' (1 = 1 :D)

Tuy nhiên đây chỉ là một trường hợp tham khảo vì nếu biến $password được lọc kỹ thì cũng sẽ vẫn dùng được nhưng để an toàn hơn ta nên hạn chế tối đa các biến cần kiểm tra, vì vậy sẽ dùng trường hợp thứ 2, như thế chỉ còn 1 biến duy nhất cần kiểm tra là $name.

Trong số hàm có khả năng lọc thì L khuyên nên sử dụng hàm addslashes(), cú pháp của hàm này là:

addslashes( string )

Ví dụ:

<?php

$string = " ' OR '1'='1' ";
echo addslashes( $string ); // Kết quả trả về là: ' OR '1'='1'

?>

Ở trên cũng chưa chắc an toàn vì biến $string này chỉ mới được addslashes() lọc nhưng điểm quan trọng là biến $string này vẫn là: ' OR '1'='1' vì chưa có dòng nào khai báo $string = addslashes( $string ) cả. Vì thế ở trước câu lệnh của trường hợp 2 phải khai báo là: $username = addslashes( $username ). Sau đó sẽ bao gồm 2 bước kiểm tra cuối cùng là: Kiểm tra username này có tồn tại hay không, Nếu tồn tại thì tiếp tục Kiểm tra password của username này có đúng hay không.

PS: Khi bạn muốn lấy thông tin từ form thì bạn nên để method = post, vì sao thì bạn tự tìm hiểu.

Để dễ hiểu L tổng hợp lại từ đầu đến cuối có code hoàn chỉnh như sau: (Ngoại trừ table users tee-hee)

<?php

$username = $_POST['username'];
$username= addslashes( $username);

$query = mysql_query("SELECT * FROM users WHERE name='$name'");
$result = mysql_fetch_array( $query );

// Kiểm tra username này có tồn tại hay không
if ( mysql_num_rows( $query ) == 0 )
{
print "Username không tồn tại!";
}

// Kiểm tra password của username này có đúng hay không
if ( $password != $result['password'] )
{
print "Mật khẩu không đúng!";
}

print "Congratulations :d":

?>