2010-07-26 64 views
4

我刚开始使用PHP和mySQL,需要知道这是否“安全”。登录信息通过AJAX(jQuery)传递到下面的PHP文件中。PHP AJAX登录,这种方法是否安全?

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(); 

我知道这可能不是做的事情,但最好的方式,这是我知道的方式!我只想知道它是否有任何重大的安全缺陷。这对我来说更像是一个概念,因此我没有合并SSL。

+2

stripslashes($ user); ?我高度怀疑您已激活MAGIC_QUOTE并激活了REGISTER_GLOBAL。这两个功能已被弃用,并强烈建议不要使用。 http://ca.php.net/manual/en/security.magicquotes.php http://php.net/manual/en/security.globals.php – HoLyVieR 2010-07-26 16:35:33

回答

5

你应该让这种变化,以防万一人们有一个反斜杠在他们的密码:

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

首先MD5是非常糟糕的。 md5()mysql_real_escape_string()也是多余的。碰撞已经在野外产生了。 sha1()虽然减弱仍然更安全,没有产生冲突(还)。最好的选择是sha256 in php,或使用mhash库。

$pass = md5($pass); 

您还需要salt the password.

+0

感谢您的信息;我知道我需要将其更改为SHA,但是在我的第一次尝试中这不起作用。我没有听说过腌制,所以再次感谢信息! – Phil 2010-07-26 16:23:39

+0

现在我感到很蠢。我的数据库中的VARCHAR被限制为50,所以当SHA1将它切断时,现在排序,谢谢。 – Phil 2010-07-26 20:07:24

+0

@Phil不用担心。我喜欢“文本”数据类型,但散列总是相同的大小,所以无论如何varchar可能会更好。 – rook 2010-07-26 20:33:13

5

它从

  • 遭受了未加密的连接发送密码(使用HTTPS至少发送用户名和密码。这可以防止被动攻击者,但不是针对活跃的密码要避免主动安全攻击者,你必须加密所有的通信)。
  • 将密码存储在数据库中(您应该改为存储盐味散列)。
+0

这是一个娱乐项目,因为它是我的学校假期!由于这只是一个项目,我不愿意为SSL证书付费,除非我真的将其用于真正的使用。感谢Salted哈希建议! – Phil 2010-07-26 16:26:07

+0

@Phil嗯,严格来说你不需要SSL来做安全认证,你可以使用[摘要认证]的变体(http://en.wikipedia.org/wiki/Digest_authentication)。但是在这种情况下,我相信你不能存储盐渍散列(可以,但是如果暴露了数据库数据,攻击者可以以任何用户身份登录)。 – Artefacto 2010-07-26 16:29:28

+0

@Atrefacto ...实际上'$ pass = md5($ pass);'(第7行)。我相信他存储MD5哈希 - 不是很安全,但它*不是*纯文本。 – 2010-07-26 16:48:44

4

也永远不会告诉用户像“用户不存在”或“不正确的密码”。如果你只是打印出“不正确的用户名或密码”,那么每个人都无法检查现有的用户名,然后尝试猜出这些密码。

+0

我知道这个问题,但是因为这是一个我用来学习PHP和mySQL的项目,所以我认为将一些更多的功能合并会更有趣。 jQuery实际上从PHP文件中提取返回的数据,并基于此改变CSS。所以当用户名输入模糊时,背景变成绿色。尽管出于显而易见的原因,我还没有将其应用于密码!谢谢! – Phil 2010-07-26 16:29:19

+0

我个人不喜欢这个选项。然后我不知道我是否有错误的用户名或密码。如果您担心这个问题,请限制每个用户名的尝试。 – Artefacto 2010-07-26 16:30:35

+0

如果用户名错误,则变为红色。你就是这么知道的。 – Phil 2010-07-26 16:43:19

1

了session_register()已过时,你应该使用$ _SESSION []。

您还在散列密码字符串$ pass上执行字符串转义;它将始终有一个十六进制值,因此不需要转义。你可以在哈希前的密码字符串上执行转义,但这只是非常有用的(例如,如果你允许用户保存包含需要转义的字符的密码短语,通常我不允许在代码的注册端) 。你也应该使用盐。

1

此基础上我的研究:

  1. 使用jQuery AJAX登录是作为普通的旧形式的安全。数据总是通过http请求发送。
    参考:ajax safe for login?
  2. 在登录表单中使用SSL(https)可提供额外的安全性。
  3. 而不是使用的mysql_connect,你应该使用预处理语句
    参考:why prepared statement?prepared statement usage example
  4. 你应该使用单向密码散列算法,如Bcrypt。单向散列算法意味着您无法将散列密码转换回纯文本。但是您可以根据存储在数据库中的散列密码来验证输入的密码。
    参考:don't encrypt password, hash it instead.the Bcrypt and how to use it