大家好,非常感谢您帮助回答这个相当复杂的问题。请不要解雇我,我保证这很容易理解!
何时以及如何在以下会员资格网站的login.php和login_validation.php的上下文中对$ _SESSION和$ _COOKIE变量进行模糊处理(如果有的话)?
这个基于会员的网站是用PHP编写的,并使用mysql作为其关系数据库。
<?php
//Connect to database
$email = $_POST['email']; //from a text field
$password = $_POST['password']; //from a password field
$password= md5($password);
$stayLoggedIn= $_POST['stayLoggedIn']; //from a checkbox, value="yes" for checked, value="no" for unchecked
$sql = "SELECT id
FROM users
WHERE email='$email' AND password='$password'";
$query=mysql_query($sql);
if(mysql_num_rows($query)==1){
$row = mysql_fetch_array($query);
$id = $row["id"];
$encodedID_session= base64_encode("iofj4983rn9dh83$id");
$_SESSION['id'] =$encodedID_session;
if($stayLoggedIn== 'yes'){
$encodedID_cookie=base64_encode("dj02359t5ng842$id");
setcookie("idCookie", $encodedID_cookie, time()+60*60*24*7, "/");
setcookie("passwordCookie", $password, time()+60*60*24*7, "/");
}
}
?>
他有一个名为login_validation.php的文件,该文件位于网站每个页面的顶部(login.php除外)。
首先它解码会话和cookie变量(如果它们被设置)(下面解码会话变量的例子)
$decodedID = base64_decode($_SESSION['id']);
$array = explode("iofj4983rn9dh83", $decodedID);
$id = $array[1];
然后它只执行以下操作之一:
开发人员做了一些事情,我让我有点困惑,比如混淆会话变量,或混淆两个(而不是一个)cookie。另外,他使用base64进行混淆的方法似乎很容易受到威胁,如果有人抓住他附加的无意义字符串。
何时以及如何在这个基于会员的网站的login.php和login_validation.php上下文中(如果有的话)$ _SESSION和$ _COOKIE变量?
谢谢,谢谢!
编辑:只是为了澄清我没有为此代码支付任何费用,而是我正在尝试学习php并从php教程中获取此代码,看起来它可以改进。
编辑2:密码现在在验证之前进行哈希
答案 0 :(得分:5)
您无需对_SESSION
变量中存储的任何内容进行模糊处理。它不会发送给客户端,因此您可以信任敏感信息。
我建议您为每个登录用户生成并存储唯一的身份验证令牌。 PHP即使在用户注销后也会维护会话(PHP不知道“登录”和“注销”),因此请保留idCookie并将其值与用户ID一起存储,例如:
if ($stayLoggedIn) {
$token = sha256(generateRandomNumber());
$_SESSION["token"] = $token;
$_SESSION["userid"] = $id;
setcookie("authenticationtoken", $token, ...)
}
验证身份验证时,检查“authenticationtoken”cookie是否与存储的会话变量匹配。身份验证令牌必须是随机的,永远不会重复使用。当用户注销时取消设置会话的“令牌”和“用户ID”变量。
现在你拥有它的方式意味着攻击者可以通过网络观察cookie并进行简单的反向md5查找(很容易生成字母数字字符串的彩虹表)来获取用户的密码。攻击者还可以轻松猜出其他用户的会话ID。
请记住在任何地方都使用https来防止cookie被盗。如果您通过http发送身份验证令牌,那么您甚至不用担心检查密码(想想Firesheep)。
此外,这很重要,不要在您的数据库中存储明文密码。您应该使用类似bcrypt(在PHP中有一个函数)来存储密码。如果攻击者破坏了您的数据库,那么他们已经获得了所有您用户的密码。这是一件坏事(想想Playstation Network)。
同样重要:确保您清理用户输入。不要只是将用户输入直接传递给数据库。您需要正确转义任何特殊的SQL字符,否则您很容易受到SQL注入。