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 )
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ụ:
Ở 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)
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 )
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:
<?php
$string = " ' OR '1'='1' ";
echo addslashes( $string ); // Kết quả trả về là: \' OR \'1\'=\'1\'
?>
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:
<?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":
?>