【问题标题】:Obfuscate (if at all) $_SESSION and $_COOKIE variables?混淆(如果有的话)$_SESSION 和 $_COOKIE 变量?
【发布时间】:2011-07-27 15:51:17
【问题描述】:

大家好,非常感谢您在回答这个相当复杂的问题时提供的帮助。请不要嫌弃我,我保证它很容易理解!

您应该何时以及如何在上下文中对以下基于会员的网站的 login.php 和 login_validation.php 进行混淆(如果有的话)$_SESSION 和 $_COOKIE 变量

这个基于会员的网站是用 php 编写的,并使用 mysql 作为它的关系数据库。

login.php

<?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)。

login_validation.php

如果设置了会话和 cookie 变量,首先它会对其进行解码(下面是解码会话变量的示例)

$decodedID = base64_decode($_SESSION['id']);
$array = explode("iofj4983rn9dh83", $decodedID);
$id = $array[1]; 

然后它只执行以下操作之一:

  • 如果未设置会话和 cookie,则会显示标题“您尚未登录”
  • 如果设置了会话,它会查询 mysql 以查找与同一行中的人的姓名 他或她的 id 并显示个性化标题“您已登录, 欢迎 Bonzo!”
  • 如果未设置会话但设置了 cookie(例如用户选择 在LoggedIn,关闭他的电脑,并打开一个新的浏览器)它查询mysql找到 与他或她的 id 位于同一行的人的姓名并显示 个性化标题“您已登录,欢迎 Bonzo!”

开发人员做了一些让我有点困惑的事情,比如混淆会话变量,或者混淆两个(而不是一个)cookie。此外,如果有人掌握了他附加的无意义字符串,他使用 base64 进行混淆的方法似乎很容易受到威胁。

您应该何时以及如何在上下文中混淆(如果有的话)$_SESSION 和 $_COOKIE 变量,以将此基于会员的网站的 login.php 和 login_validation.php 混淆?

谢谢,谢谢!

编辑:只是为了澄清我没有为这段代码付钱给任何人,相反,我正在尝试学习 php,并从一个看起来可以改进的 php 教程中获得了这段代码。

编辑 2:密码现在在验证之前经过哈希处理

【问题讨论】:

  • 你为什么要混淆 $_SESSION 值?除非您认为您的服务器已被入侵,否则它们只有您的应用程序知道;它们存储在您的服务器上,而不是客户端上。
  • 不要将密码的 MD5 哈希值保存在 cookie 中。
  • 另外,你见过Little Bobby Tables吗?你们会是好朋友。你说的是“开发商”,如果你付钱给他,就拿回你的钱。
  • 密码在cookie中经过哈希处理,但在数据库中以明文形式存储?它应该在数据库中散列(最好使用比 md5 更好的东西,加上盐),而不是存储在 cookie 中。
  • 啊,又是一个弊大于利的无用 PHP 教程 :(

标签: php mysql session cookies obfuscation


【解决方案1】:

您不需要混淆存储在_SESSION 变量中的任何内容。它不会发送给客户端,因此您可以信任它来处理敏感信息。

我建议您为每个登录的用户生成并存储一个唯一的身份验证令牌。 PHP 会在用户注销后保持会话(PHP 不知道“登录”和“注销”),因此保留 idCookie 并将其值与用户 ID 一起存储,例如:

if ($stayLoggedIn) {
    $token = sha256(generateRandomNumber());
    $_SESSION["token"] = $token;
    $_SESSION["userid"] = $id;
    setcookie("authenticationtoken", $token, ...)
}

当您验证身份验证时,请检查“authenticationtoken”cookie 是否与存储的会话变量匹配。身份验证令牌必须是随机的并且从不重复使用。当用户注销时,取消设置会话的“token”和“userid”变量。

您现在拥有它的方式意味着攻击者可以通过网络查看 cookie 并执行简单的反向 md5 查找(字母数字字符串的彩虹表很容易生成)来获取用户的密码。攻击者还可以轻松猜出其他用户的会话ID。

记得在任何地方都使用 https 来防止 cookie 被窃取。如果您通过 http 发送身份验证令牌,那么您甚至可以不用检查密码(想想 Firesheep)。

另外,这很重要,不要在数据库中存储明文密码。您应该使用 bcrypt 之类的东西(PHP 中有一个函数)来存储密码。如果攻击者破坏了您的数据库,那么他们已经获得了所有您用户的密码。这是一件坏事(想想 Playstation 网络)。

同样重要的是:确保清理用户输入。不要只是将用户输入直接传递给数据库。您需要正确转义任何特殊的 SQL 字符,否则您很容易受到 SQL 注入的攻击。

【讨论】:

  • 等待,同时去洗澡。顺便说一句,我把你的答案读了两遍,已经有了一些深刻的见解,所以谢谢。会回来看看你在改变什么。
  • 好答案。如果 GUID 用于用户 ID,那么观察“垃圾 + 用户 ID”的人将无法开始准确猜测会话 ID,但不知何故,我觉得这不太可能。仍然存在同一用户始终获得相同会话 ID 的问题。
  • Cameron,这不是在数据库中存储明文密码。请阅读我在帖子下对 Aether 的最新评论。
  • 好的。最初的问题(在编辑之前)是对提交的密码进行 SQL 选择。尽管如此,存储密码的单个 MD5 散列并不安全。你真的应该看看 bcrypt,或者至少存储一个加盐的、迭代的哈希。请参阅chargen.matasano.com/chargen/2007/9/7/… 以获得有关如何存储密码的详细讨论。带回家的信息是您需要一个随机的、每个用户的盐和一个慢速散列函数。没错,一个slow散列函数。
  • 您好,Cameron,感谢您重新提出问题并保持联系。我今天花了一些时间阅读 phppass 的文档(一个随机的,每个用户的盐,慢速具有功能)openwall.com/phpass 并将立即设置它。我也将在这个问题上提出一些悬赏,其中包含一些关于我将如何设置 cookie 和会话的示例代码,以澄清我的方式是否包含所有建议的改进,因此请注意这一点。再次感谢。
猜你喜欢
  • 1970-01-01
  • 2010-09-10
  • 2012-07-02
  • 2012-05-17
  • 1970-01-01
  • 1970-01-01
  • 2019-08-07
  • 2020-06-30
  • 2014-06-13
相关资源
最近更新 更多