使用Ajax登录系统的安全性

时间:2013-01-03 13:39:16

标签: php javascript jquery mysql ajax

我已经制作了一个登录系统,该系统使用了基本的ajax请求和一些反馈,并且运行良好(代码位于底部)。

除了我要插入的哈希和盐渍密码(所以不要挂断),使用Ajax / jQuery有什么安全隐患处理这些要求:最重要的是:

  1. 当涉及到JS依赖而不是纯PHP时,一般的观点是什么?人们放弃裁员,简单地说这是一个只有JS的网站(网站的大量数据)是合法的吗?是基于Twitter引导程序,所以它有点依赖于JS)。

  2. 我的PHP和JS是否以正确的方式连接? (我的饼干还能用吗?)

  3. 如何创建一种安全的方式来使用jQuery .load()在成功登录后引入我的内容?

  4. 关于使我的系统安全的任何一般性建议?。

     $(function login() {
    
     $("form .button").click(function () {
    
     // getting form values and assigning variable names
     var username = $("form #username").val();
     var password = $("form #password").val();
     var remember = $("form #remember").val();
    
     // concatenating variables to form the data used by the Ajax post method
     var dataString = 'username=' + username + '&password=' + password + '&remember=' + remember;
    
     // begin Ajax post function
     $.ajax({
         type: "POST",
         url: "controls/login/process.php",
         data: dataString,
         success: function (response) {
             if (response == 'success') {
                 alert("SUCCESS");
             } else {
                 $('.alert').find('span').text('Incorrect username or password');
                 $('.alert').addClass('alert-error').fadeIn('fast');
             }
         },
         error: function () {
             $('.alert').find('span').text('An error occured, try again');
             $('.alert').addClass('alert-error').fadeIn('fast');
    
         }
     });
    
     return false;
    
     });
     });
    
  5. 这与

    接口
    <?php
    session_start();
    // Starting the session
    require '../../tools/db/connect.php';
    // Including the database connection file
    session_set_cookie_params(2*7*24*60*60);
    // Making the cookie live for 2 weeks
    
    if($_SESSION['reference'] && !isset($_COOKIE['unifyLogin']) && !$_SESSION['remember']){
        // If you are logged in, but you don't have the cookie and you have not checked the remember checkbox (a browser restart), destroy the session 
        $_SESSION = array();
        session_destroy();
        echo "expired";
    }
    
    $_POST['username'] = mysql_real_escape_string($_POST['username']);
    $_POST['password'] = mysql_real_escape_string($_POST['password']);
    $_POST['remember'] = (int)$_POST['remember'];
    // Escaping all input data
    $row = mysql_fetch_assoc(mysql_query("SELECT ID,REFERENCE FROM USER WHERE USERNAME='{$_POST['username']}' AND PASSWORD='{$_POST['password']}'"));
    
    if($row['REFERENCE']) {
    $_SESSION['secure'] =  false;
    // If everything is OK login
    $_SESSION['id'] = $row['ID'];
    $_SESSION['reference'] = $row['REFERENCE'];
    $_SESSION['remember'] = $_POST['remember'];
    // Store some data in the session
    setcookie('unifyLogin',$_POST['remember']);
    // We create the cookie
    echo "success";
    } else {
    echo "failure";
    }
    
    ?>
    

5 个答案:

答案 0 :(得分:2)

确保网站安全的最佳方法是使用SHA-512加密密码。

$rounds = 5000
$cryptedPwd = crypt($password, '$6$rounds=' . $rounds . '$SOMeSILLySTrInG$');

要解密:

$pwdEntered = trim($_POST['password']);
if (crypt($pwdEntered, $pwdHashed) == $pwdHashed){
// do something
}

您还可以添加强力保护,可能还有日志文件......

我建议你使用PDO而不是普通的mysql连接。

答案 1 :(得分:1)

  

当涉及JS依赖的时候,一般的观点是什么?   反对纯PHP - 人们是否裁员,是否合法   简单地说这是一个只有JS的网站(该网站的数量很大   基于Twitter引导,所以它有点依赖于JS)。

     

我的PHP和JS是否以正确的方式连接? (我的饼干还能用吗?)

很难说有多少人今天使用互联网禁用javascript,但你的javascript不应该是阻碍,你的网站应该仍然可以使用javascript禁用。做起来并不难。您应该使用.click()并将其绑定到表单,而不是使用.submit()进行AJAX查询。这样你仍然可以通过PHP处理表单。

这也是最好的做法之一,不要在提交按钮上绑定.click()事件,否则我无法通过按Enter提交表单。

然后在PHP中,您将能够通过检查$_SERVER['X-Requested-With']来了解是否已从jQuery发送请求。

然后你可以有两种不同的行为:

if ( isset( $_SERVER['X-Requested-With'] ) ) {
    // comes from jQuery
} else {
    // basic submit
}

我认为这大致是您应该如何界面应用。

  

如何创建一种安全的方式来使用jQuery .load()来引入我的   成功登录后的内容?

您可以从PHP返回true或false。或者,如果您需要重新显示某些数据,则可以传递json对象。假设您有一组要传回的数据

PHP

if ( isset( $_SERVER['X-Requested-With'] ) ) {
    $data = array('success' => true , 'username' => $username );
    return json_encode( $data );
}
  

关于使我的系统安全的任何一般性建议?。

您通过POST(通过AJAX)发送数据,这并不比以正常方式发布数据更安全。

答案 2 :(得分:1)

回答问题#3:在将不可信数据插入HTML时对其进行转义和清理,就像对传统的&#34; PHP网站。如果服务器返回未转义的文本,请使用jQuery的.text()方法将文本插入元素中; 不要将文字插入HTML (例如$(...))。

我认为问题#1的答案已经很明确了;有一小部分用户(包括搜索引擎)无法或出于隐私或安全原因选择不运行JavaScript。您可能不想拒绝为他们提供服务。

关于问题#2和#4的评论如下。


var dataString = 'username=' + username + '&password=' + password + '&remember=' + remember;

jQuery可以为你做到这一点(包括逃避你缺少的查询字符串)。只需将它们存储在一个对象中,您可以将其传递给jQuery而不是字符串:

var dataObject = {
    username: username,
    password: password,
    remember: remember
};

另请注意jerome.s的建议,将AJAX响应作为JSON返回,并避免弃用jQuery功能。对于JSON响应,请确保最外层对象是对象,而不是数组。


$_POST['username'] = mysql_real_escape_string($_POST['username']);
$_POST['password'] = mysql_real_escape_string($_POST['password']);
$_POST['remember'] = (int)$_POST['remember'];
// Escaping all input data
$row = mysql_fetch_assoc(mysql_query("SELECT ID,REFERENCE FROM USER WHERE USERNAME='{$_POST['username']}' AND PASSWORD='{$_POST['password']}'"));

自PHP 5.5起,PHP MySQL扩展为deprecated。我会使用MySQLi扩展或PDO。两者都提供预准备语句,允许您避免手动SQL转义参数值。

要实施per-user salts,您需要更改此查询。具体来说,您必须检索散列密码和相应的salt,然后使用该盐散列输入的密码。如果密码正确,则计算的哈希值应与存储在数据库中的哈希值匹配。


if($row['REFERENCE']) {
$_SESSION['secure'] =  false;
// If everything is OK login
$_SESSION['id'] = $row['ID'];
$_SESSION['reference'] = $row['REFERENCE'];
$_SESSION['remember'] = $_POST['remember'];
// Store some data in the session
setcookie('unifyLogin',$_POST['remember']);
// We create the cookie
echo "success";

PHP使用相当宽松的会话处理模型,因为它将接受任意会话ID值,并且您的代码在成功登录后不会重新生成会话ID。因此,您的网站可能容易受到session fixation攻击。

我也没有看到任何针对&#34;登录CSRF&#34;或clickjacking

另请注意Jeffrey的评论:&#34;如果在数据库中未找到匹配项,则行if($row['REFERENCE']) {将生成错误&#34;。

编辑:您还应对失败的登录尝试实施速率限制(以减慢自动密码猜测速度)。

答案 3 :(得分:1)

我发现的最好的密码安全方法是php的内部方法,当然使用php进行登录时。

http://php.net/manual/en/function.password-hash.php

password_hash(&#34; rasmuslerdorf&#34;,PASSWORD_DEFAULT);

password_verify(&#39; rasmuslerdorf&#39;,$ hash);

它将盐存储在您的数据库中,并为您进行所有轮次检查。

经过几个小时的阅读加密后,我花了很长时间才找到这种方法。安全性不仅可靠,而且使用起来非常简单。

我建议您通过帖子发送信息然后使用它。另外在往返旅行中,如果你没有往返,有人可以跳过你的javascript哈希并使用纯哈希登录。这样,如果他们试图使用哈希,它会重新哈希它并将其作为错误的pw返回,这就是它的本质。

答案 4 :(得分:0)

您使用JS作为与服务器交互的另一种方式,而不是常规浏览。因此它的安全性不会低于您要求的任何其他页面。

如果您将登录信用证发布到PHP页面以检查登录信息,请像存储常规请求(可能是会话)一样存储信息。现在,每次使用AJAX从服务器请求数据时,请在发送回数据之前再次检查服务器端的会话。如果未经授权,只需返回错误。在JS中,您现在可以检查响应并基于此采取行动。

我建议使其安全,就像开发常规浏览器一样,开发每一页。如果你能做到这一点,那么在使用AJAX时它也是安全的。

作为非安全建议。除非你愿意牺牲一些访客(旧款手机,平板电脑或只是js禁用的浏览器),否则不要制作仅限javascript的网站。