0

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

除了我将要输入的散列和加盐密码(所以不要挂断),使用 Ajax/jQuery 处理这些请求的安全含义是什么:最重要的是:

  1. 当涉及到这是依赖于 JS 而不是纯 PHP 时,一般的看法是什么 - 人们是否进行了冗余,简单地说这是一个仅限 JS 的网站是否合法(大量网站基于 Twitter 引导程序,所以它有点依赖于 JS)。

  2. 我的 PHP 和 JS 接口是否正确?(我的 cookie 还能用吗?)

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

这与

<?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";
}

?>
4

5 回答 5

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 连接。

于 2013-01-03T13:47:15.827 回答
1

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

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

password_hash("rasmuslerdorf", PASSWORD_DEFAULT);

password_verify('rasmuslerdorf', $hash);

它将盐存储在您的数据库中,并为您进行全方位检查。

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

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

于 2015-03-06T14:24:17.867 回答
1

当涉及到这是依赖于 JS 而不是纯 PHP 时,一般的看法是什么 - 人们是否进行了冗余,简单地说这是一个仅限 JS 的网站是否合法(大量网站基于 Twitter 引导程序,所以它有点依赖于 JS)。

我的 PHP 和 JS 接口是否正确?(我的 cookie 还能用吗?)

很难说今天有多少人在禁用 javascript 的情况下使用互联网,但是您的 javascript 不应该是令人讨厌的,并且您的网站应该仍然可以在禁用 javascript 的情况下工作。做起来并不难。而不是使用.click()AJAX 查询,您应该使用.submit()它并将其绑定到您的表单。这样,您仍然可以仅通过 PHP 处理表单。

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

然后在您的 PHP 中,您将能够通过检查$_SERVER['X-Requested-With'].

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

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),这并不比以正常方式发布数据更安全。

于 2013-01-03T14:08:14.170 回答
1

回答问题 #3:在将不受信任的数据插入 HTML 时对其进行转义和清理,就像您对“传统”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 MySQL 扩展自 PHP 5.5 起已弃用。我会使用 MySQLi 扩展或 PDO。两者都提供准备好的语句,允许您避免手动 SQL 转义参数值。

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


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。因此,您的网站可能容易受到会话固定攻击。

我也没有看到任何针对“登录 CSRF”或点击劫持的保护措施。

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

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

于 2013-01-03T15:35:33.327 回答
0

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

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

我建议使其安全的方法是开发每个页面,就好像它是由常规浏览器请求的一样。如果你能做到这一点,它在使用 AJAX 时也是安全的。

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

于 2013-01-03T13:47:28.483 回答