我已经制作了一个登录系统,该系统使用了基本的ajax请求和一些反馈,并且运行良好(代码位于底部)。
除了我要插入的哈希和盐渍密码(所以不要挂断),使用Ajax / jQuery有什么安全隐患处理这些要求:最重要的是:
当涉及到JS依赖而不是纯PHP时,一般的观点是什么?人们放弃裁员,简单地说这是一个只有JS的网站(网站的大量数据)是合法的吗?是基于Twitter引导程序,所以它有点依赖于JS)。
我的PHP和JS是否以正确的方式连接? (我的饼干还能用吗?)
如何创建一种安全的方式来使用jQuery .load()在成功登录后引入我的内容?
关于使我的系统安全的任何一般性建议?。
$(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";
}
?>
答案 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的网站。