PHP AJAX login, is this method secure?

2020-02-26 02:35发布

问题:

I have just started PHP and mySQL and need to know if this is "safe". The login information is passed into the following PHP file through AJAX (jQuery).

jQuery AJAX

$("#login_form").submit(function(){
    $.post("login.php",{user:$('#username').val(),pass:$('#password').val()} ,function(data)

PHP

ob_start();
mysql_connect("-", "-", "-") or die("ERROR. Could not connect to Database."); 
mysql_select_db("-")or die("ERROR. Could not select Database.");

//Get Username and Password, md5 the password then protect from injection.

$pass = md5($pass);
$user = stripslashes($user);
$pass = stripslashes($pass);
$user = mysql_real_escape_string($user);
$pass = mysql_real_escape_string($pass);

//See if the Username exists.
$user_result=mysql_query("SELECT * FROM users WHERE username='$user'");
$user_count=mysql_num_rows($user_result);

if($user_count==1){
    if($pass_length==0){ echo "userVALID"; }
    else{       
        $pass_result=mysql_query("SELECT * FROM users WHERE username='$user' and password='$pass'");
        $pass_count=mysql_num_rows($pass_result);       
        if($pass_count==1){             
            session_register("user");
            session_register("pass"); 
            echo "passVALID";
        }
        else { echo "passERROR"; }      
    }
}
else { echo "userERROR"; }

ob_end_flush();

I know this may not be the best way to do things but, it is the way I know! I just want to know if it has any major security flaws. It is more of a concept for me and therefore I am not incorporating SSL.

回答1:

You should make this change just in case people have a backslash in their password:

if(get_magic_quotes_gpc()){
   $user = stripslashes($user);
   $pass = stripslashes($pass);
}
$user = mysql_real_escape_string($user);
$pass = sha256($salt.$pass);

First and foremost md5 is very bad. Also md5() and mysql_real_escape_string() is redundant. Collisions have been generated in the wild. sha1() although weakened is still much more secure and no collisions have been generated (yet). The best choice would be sha256 in php, or using the mhash library.

$pass = md5($pass);

You also need to salt the password.



回答2:

It suffers from

  • Sending the password over an unencrypted connection (use HTTPS at least to send the username and password; this protects the password against passive attackers but not against active ones. To be secure against active attackers, you must encrypt all the communications).
  • Storing the password in the database (you should store a salted hash instead).


回答3:

Also never tell user things like "user doesn't exist" or "incorrect password". It's much better if you just print out "Incorrect username or password" so everyone cannot check for existing usernames and then try to guess password for these.



回答4:

session_register() is deprecated, you should be using $_SESSION[].

You're also performing your string escapes on a hashed password string $pass; it will always have a hex value and so doesn't need to be escaped. You can perform escapes on the password string before the hash, but that's only marginally useful (e.g., if you allowed passphrases to be saved by users that included characters that needed to be escaped. Generally I disallow this on the registration side of the code). You should also use a salt.



回答5:

Base on my research:

  1. using jquery ajax to login is as safe as plain old form. data is always sent through http request.
    reference: ajax safe for login?
  2. use SSL (https) in login form gives extra security.
  3. instead of using mysql_connect, you should use prepared statements
    reference: why prepared statement? and prepared statement usage example
  4. you should use one-way password hashing algorithm, such as Bcrypt. one-way hashing algorithm means you cannot convert hashed password back to plain text. but you can verify the keyed in password against the hashed password stored in database.
    reference: don't encrypt password, hash it instead. and the Bcrypt and how to use it