【问题标题】:PHP Cookie Security [closed]PHP Cookie 安全 [关闭]
【发布时间】:2013-06-22 16:30:54
【问题描述】:

我有这个安全页面。只是想问一下我的cookie登录是否应该有什么我需要担心的。我不使用 mysql 来保存用户数据,因为只有管理员需要访问该页面。你能告诉我安全登录页面的任何缺陷吗?黑客将如何破解这个安全的主页面?我还需要做些什么来使其更安全。非常感谢。

<?php
$salt = 'a|s534#ihtuQb84z<xIR_ kU;L~?-A?-x|u+Njw##Us(Pi(-hM+YmiQF`Bz[Bl -';
$salt2 = ',/Da|H#s7cWINVi&a4wy9Qc&gVrF*o)u(XoidF?-8w=vkzLRLN4U9 #u88T5818E';

//checks for post details
if (isset($_POST['user'], $_POST['pass'])) {

//santizes the details
$user = preg_replace('/[^A-Za-z0-9]/','', $_POST['user']);
$pass = preg_replace('/[^A-Za-z0-9]/','', $_POST['pass']);

//check if user exists
    if (($user === 'admin1' && $pass === 'pass1') ||
        ($user === 'admin2' && $pass === 'pass2') ||
        ($user === 'admin3' && $pass === 'pass3')) {


        //i can make it that the $user will also be hashed just in case i need to
        $cookiemd5 = $user.'-'.sha1(crypt($pass, $salt).md5($_SERVER["REMOTE_ADDR"].$salt2.$_SERVER["HTTP_USER_AGENT"]));


            if (intval($_POST['rememberme']) === 1) {
                setcookie("temp", $cookiemd5, time()+60*60*24*365, "/", ".domain.com", false, true);
            } else {
                setcookie("temp", $cookiemd5, false, "/", ".domain.com", false, true);
            }

        header("Location: /secure.php"); exit();

    } else {

        header("Location: /secure.php"); exit();

    }

}  elseif($_GET['do'] === 'logout') {

        setcookie("temp", "", time()-2592000, "/", ".domain.com", false, true);

        header("Location: /secure.php"); exit();

} elseif (isset($_COOKIE['temp'])) {

    $details = explode('-', $_COOKIE['temp']);


    if (($details[0] == 'admin1' && $details[1] == sha1(crypt('pass1', $salt).md5($_SERVER["REMOTE_ADDR"].$salt2.$_SERVER["HTTP_USER_AGENT"]))) ||
        ($details[0] == 'admin2' && $details[1] == sha1(crypt('pass2', $salt).md5($_SERVER["REMOTE_ADDR"].$salt2.$_SERVER["HTTP_USER_AGENT"]))) ||
        ($details[0] == 'admin3' && $details[1] == sha1(crypt('pass3', $salt).md5($_SERVER["REMOTE_ADDR"].$salt2.$_SERVER["HTTP_USER_AGENT"])))) { 
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++       
//+++++++++++++++++++++ EVERYTHING STARTS HERE AFTER LOGIN ++++++++++++++++++++++++++++++++++++++
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
?>




<?php 
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++       
//+++++++++++++++++++++ EVERYTHING ENDSSS HERE AFTER LOGIN ++++++++++++++++++++++++++++++++++++++
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
} else { setcookie("temp", "", time()-2592000, "/", ".domain.com", false, true); header("Location: /secure.php"); }
} else {  echo'<form name="login" method="post" action="secure.php"> Username: <input type="text" name="user"><br> Password: <input type="password" name="pass"><br>  Remember Me: <input type="checkbox" name="rememberme" value="1"><br> <input type="submit" name="submit" value="Login!"></form>'; } ?>

编辑.... 这个简单的 PHP 会话登录怎么样……这比 cookie 安全得多吗?

<?php
session_start();

if ($_SESSION['logged_in'] == true) {
//++++++++++++++++ secure data start +++++++++++++++++++



//++++++++++++++++ secure data end +++++++++++++++++++
} elseif ($_POST['user'] == 'admin' && $_POST['pass'] == 'H@rDP@s$w0rD98741') {

    $_SESSION['logged_in'] = true;


} else {

    session_destroy();

}


?>

【问题讨论】:

  • 简单明了:为什么不用会话?它们很简单,可以让服务器控制登录有效性。
  • 像 AbsoluteƵERØ 所说的那样看起来不错。您可以添加一个睡眠,例如4000 毫秒阻止每次登录检查的暴力攻击
  • @alex 4000ms 听起来有点刺耳,我想你的意思是 400ms
  • @Oleg 取决于登录的目的,我使用 5000 毫秒,因为它只是一次登录,因此不会影响工作流程。
  • 使用 $_SESSION,不要编写自己的会话处理程序。这个会话处理程序很垃圾。

标签: php security session cookies login


【解决方案1】:

为这个 cookie 添加盐和创建摘要有什么意义?生成一个随机字符串会更好,对吧?顺便说一句,如果您通过网络发送纯密码,那么安全问题就是错误的!

如果您使用 cookie 字符串解密并从中找到一些信息,那么加密 cookie 而不是散列它是一个很好的逻辑。在这种情况下,我个人更喜欢随机字符串。

我看到你接收脚本密码的方式是一个普通的请求参数,这打破了这个脚本中的第一个安全环,我可以简单地从行中嗅出你的密码。使 cookie 安全并不能解决所有访问安全问题。

如果我错了,请纠正我:)

谢谢

【讨论】:

    【解决方案2】:

    安全在旁观者的眼中。所有的哈希听起来都很棒,但实际上看起来你从用户那里获取了一个用户名和一个密码。您要求他们始终使用相同的浏览器(或设备)并且从不升级系统(对他们来说不安全)。

    我心中的“安全”是SSL/TLS。当用户使用 WireShark 等应用程序进行连接时,这将阻止(或使其非常难)有人从网络中捕获 usernamepassword。由于它仅供管理员使用,因此最好将他们的 IP 地址列入白名单,并使用您预先共享的信息对其进行身份验证。

    与其允许他们从任何地方访问,不如让他们使用VPN 进入公司网络,如果它在网络上,他们可以访问它。

    我在这里看不到任何关于跟踪失败的登录尝试或任何类似性质的内容。所以基本上有人可以对盒子进行暴力攻击(或者如果他们知道你的密码习惯,字典)来尝试进入。所以你希望运行类似ip tables 的东西来防止这种事情发生。

    另外,您没有检查referrer,因此如果有人想尝试进入,则可以自动绕过登录页面继续点击处理程序页面。

    您还需要记录您用于在其他地方(不在代码中)创建哈希的过程,然后确保您没有在代码中以明文形式存储任何变量。这样一来,如果有人掌握了这个文件,他们就不会一次获得所有的登录信息。

    从更好的安全角度来看,您可以使 cookie 在不活动后的一定时间内过期。这将迫使用户再次登录,而不是给他们一个为期一年的 cookie,或者像 @deceze 建议的那样使用会话(只要超时是合理的)。

    【讨论】:

      【解决方案3】:

      我看到的主要问题是:

      1. cookie泄露信息,即用户id; 任何信息泄露都是可能的攻击者的钩子
      2. cookie 本质上是静态的;除非管理员的 IP 地址发生变化,否则 cookie 将始终相同
      3. 服务器无法控制用户的登录状态
      4. 代码很复杂(坦率地说非常糟糕),因此容易出错

      特别是第二点和第三点一起打破了IMO。如果攻击者设法捕获或找到一次 cookie,它将永远有效。攻击者可以简单地尝试所有可能的有效 cookie,因为 cookie 本质上是静态的。一旦他找到了秘密握手,它就永远有效,你不知道它正在发生。

      您应该使用经过实战考验的登录方法,而不是自己想出。最简单的是磨机会话的标准运行。 cookie 将包含一个有时间限制的无意义的 blob,服务器知道所有正在运行的会话,并且可以在需要时撤销它们。让这一切都通过 HTTPS 运行,您将获得前所未有的安全。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-10-08
        • 2011-07-04
        • 2011-04-17
        • 1970-01-01
        • 2011-07-13
        • 2014-07-16
        相关资源
        最近更新 更多