在过去的几天里,它一直在我的脑海中运行,但我读了一些关于如何使PHP会话更安全的文章。几乎所有这些文章都说你需要在会话中使用额外的盐来保存useragent。像这样:
$fingerprint = md5('SECRET-SALT'.$_SERVER['HTTP_USER_AGENT']);
盐会使攻击者更难以劫持或无论什么会话。但是,为什么每次检查时都加盐:
md5('SECRET-SALT'.$_SERVER['HTTP_USER_AGENT']) == $_SESSION [ 'fingerprint' ]
为什么盐会让它更安全,因为攻击者仍然只需要使用者(相对来说是一小组不同的使用者)和sessionid?
可能是我忽视的一些小东西,但无法弄明白,让我疯狂哈哈
谢谢!
答案 0 :(得分:7)
建议添加盐的原因很简单。通常,当您创建此“指纹”时 - 如果您只使用一个具有有限数据集的数据项,则外部黑客可以更轻松地生成此数据并劫持会话。
在上面的示例中,是的,如果攻击者同时具有“指纹”和用户代理,则他们将能够劫持会话。
添加盐只会让攻击者更难以生成指纹,这是“如果他们只拥有一条信息,那么最后一条信息就会变得毫无用处”。
我建议您添加更多内容,例如,在vBulletin(我曾经使用过的项目)中,使用以下代码生成会话ID哈希(与指纹基本相同)。
define('SESSION_IDHASH', md5($_SERVER['HTTP_USER_AGENT'] . $this->fetch_substr_ip($registry->alt_ip))); // this should *never* change during a session
此外,使用
生成会话哈希md5(uniqid(microtime(), true));
尝试识别会话时都会检查这些
因此,要劫持会话,该人需要知道以下内容
他们还必须欺骗IP地址(或至少前2/3个八位字节)才能做到这一点。
如果他们实际上已经设法获得上述信息,那么他们可能会以其他方式进行攻击,而不仅仅是会话劫持。
vBulletin实际上并没有实际使用“盐”,但是,在上面的例子中,盐只是添加了有限量的熵,最好找到尽可能多的熵。
例如,在我目前用python编写的东西中,我生成了一个用于XSRF保护的哈希。以下是我使用的内容。
self.key = sha1(
self.user.username +
self.user.password +
settings.SECRET_KEY +
strftime("%a, %d %b %Y %H:%M:%S +0000", gmtime())
).hexdigest()
使用用户的用户名和密码,当前时间和预设盐来生成此信息。这对于攻击者来说很难生成由于盐和时间(但是请注意,这只是因为一旦使用它就会变得安全,随着时间的推移,这对于某人来说并不需要太多如果它没有改变,请为特定用户破解这个)
答案 1 :(得分:3)
如果您在自己的服务器上,加密会话变量毫无意义,因为它们不会离开服务器。有关详细信息,请参阅What do I need to store in the php session when user logged in?的 Linead 回答。如果您在共享服务器中,除了会话ID之外,您可能还需要加密每个会话变量,因为它们存储在您的所有邻居正在使用的同一Web服务器可读的临时文件中。
无论如何,如果你真的担心安全问题,你最好使用自己的(虚拟或非虚拟)服务器,因此危险只会来自服务器外部。
会话风险的一些例子:
所以,根据我的惯例,你可以采取一些措施:
session.use_only_cookies
。缺点:用户需要启用cookie。
(我认为你已经配置了PHP以获得最大的安全性。)
一些更极端的措施:
在某些极端情况下,您可以忘记会话并使用Apache身份验证。最简单的解决方案,但有很多限制。
答案 2 :(得分:2)
如果我理解正确,您希望阻止猜测会话ID的远程攻击者进行会话劫持?
如果不是这种情况,那么你就会严重超出你的范围 - 可以窥探流量的攻击者也可以模仿用户代理,并且无论如何攻击者都可以访问你的会话存储。
如果存储用户代理字符串以将会话“锁定”到当前用户代理,那么散列它就没有意义 - 完整用户代理字符串上的字符串比较更快(然后散列然后比较)和在存储方面没有那么昂贵。
我不认为存储用户代理提供了足够的区别 - 更好的方法是在会话开始时生成更大的ID(具有更多位)(也许sha1当前时间戳+用户名+用户代理+东西),然后将其存储在cookie和会话中,并在每个附加请求中匹配它。这并没有太大地改变攻击向量(你仍然需要猜测一些数字),但是通过大量增加攻击的难度,它很容易显着增加必须猜测成功攻击的位数。
答案 3 :(得分:1)
我看到了腌制指纹的一个目的。如果一个坏人抓住你的session-db(上帝知道原因)而不是你的代码,他就不能通过尝试针对它的普通用户代理来“猜测”你的指纹识别方法。
答案 4 :(得分:0)
我也是partially protect from session impersonation attacks那样做的。您还需要包含IP地址。
请记住,当客户端的浏览器自动更新用户代理更改时,您会认为他的会话已被劫持;)
答案 5 :(得分:0)
由于指纹存储在服务器端,因此您无需使用盐渍哈希。 “正常”散列足以减少数据。
答案 6 :(得分:0)
请记住,如果你这样做,那么如果他们升级浏览器,就会强迫别人再次登录。这可以,但只是确保这是你的意图。
使用用户的远程地址也不是没有问题。许多人使用来自不同位置的同一台计算机。移动设备,家庭和工作中使用的笔记本电脑,Wifi热点使用的笔记本电脑等。恕我直言,使用IP地址是一个坏主意,新IP地址需要登录,除非您正在处理高度敏感的信息,如网上银行。是这样的吗?
你在乎什么?外部攻击?或者在共享主机情况下,有人可以阅读您的会话信息?
如果是后者,解决方案很简单:只是不要在会话中存储任何敏感内容。任何敏感的东西都应该存储在数据库中。
在创建秘密盐方面,您需要使用不可猜测的东西。我会选择在创建用户时创建的随机字符串。如有必要,每次会话无效时重新创建它。
至于它会使它更安全,你自己说:用户代理字符串有限(不到一百个可能会覆盖99.99%的用户)。盐只会增加可能性的数量。话虽这么说,如果你在所有会话中使用相同的盐,那么在用蛮力发现它之前只是时间问题。
答案 7 :(得分:0)
好的,例如我正在使用以下虚构代码:
<?php
// The sessionid cookie is now a certain hash
if ( array_key_exists ( $_COOKIE [ 'sessionid' ] ) )
{
// Get the session from database
$db_sessid = $pdo -> getStuff ( 'session_database', $_COOKIE [ 'sessionid' ] );
if ( $db_sessid !== null && $db_sessid [ 'fingerprint' ] == sha1 ( 'SOMESALT' . $_SERVER [ 'HTTP_USER_AGENT' ] ) )
{
set_cookie ( ... ); // New sessionid and write also to DB
// User is now logged in, execute some user stuff
}
else
{
// Session doesn't exist, or the fingerprint does not match
}
}
现在攻击者仍然需要sessionid,它位于cookie中(沿HTTP标头发送)和useragent。那么附加盐还有什么意义呢?
在我看来,检查IP也不是一个好的选择,一些提供商或代理商会在每次请求时更改它们。
到目前为止感谢( - :
答案 8 :(得分:-2)
在满足所有safegard参数之后,您才允许cookie设置一个cookie,如果不满足该参数,cokkie将永远不会被设置为好,但是如果cookie具有可见的参数,那会发生什么。同样,如果条件从未满足,那么会议将得到满足。这就是您真正想要的。记住检查是否符合条件,以便通过Cookie提供会话和查看数据 记住,cokkie坐在客户浏览器上 问候Stelios