首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >PHP Sessions + Useragent with salt

PHP Sessions + Useragent with salt
EN

Stack Overflow用户
提问于 2009-03-05 20:49:26
回答 9查看 9.3K关注 0票数 4

在过去的几天里,它一直在我的脑海中运行,但我读了一些关于如何使您的PHP会话更安全的文章。几乎所有这些文章都说,您需要用一个额外的salt来保存会话中的用户代理。如下所示:

代码语言:javascript
复制
$fingerprint = md5('SECRET-SALT'.$_SERVER['HTTP_USER_AGENT']);

salt将使攻击者更难劫持或任何会话。但是为什么每次你要像这样检查时都要加盐呢:

代码语言:javascript
复制
md5('SECRET-SALT'.$_SERVER['HTTP_USER_AGENT']) == $_SESSION [ 'fingerprint' ]

那么,既然攻击者仍然只需要useragent (相对来说是一小部分不同的useragent)和sessionid,为什么salt会让它更安全呢?

可能有一些我忽略的小东西,但又弄不明白,让我发疯哈哈

谢谢!

EN

回答 9

Stack Overflow用户

发布于 2009-03-05 21:47:35

建议添加盐的原因很简单。通常,当你创建这个“指纹”时--如果你只使用一个数据项,它有一个有限的数据集,那么它使得外部黑客更容易生成它,并劫持会话。

在上面的例子中,是的,如果攻击者同时拥有“指纹”和用户代理,那么他们将能够劫持会话。

添加盐只会使攻击者更难生成指纹,这是一种“如果他们只有一条信息,那么最后一条信息就变得无用”的情况。

例如,我建议您在vBulletin (我曾经参与的一个项目)中添加一些东西,会话ID散列(基本上与指纹相同)是用以下代码生成的。

代码语言:javascript
复制
define('SESSION_IDHASH', md5($_SERVER['HTTP_USER_AGENT'] . $this->fetch_substr_ip($registry->alt_ip))); // this should *never* change during a session

此外,还使用以下命令生成会话散列

代码语言:javascript
复制
md5(uniqid(microtime(), true));

在尝试标识会话时,这两项都会被选中

因此,要劫持会话,用户需要了解以下内容

  • 创建会话时服务器上的时间(准确)用户浏览器代理字符串
  • user's IP address

他们还必须伪造IP地址(或至少前2/3个二进制八位数)才能做到这一点。

如果他们实际上已经设法获得了上述信息,那么他们很可能能够通过其他方式进行攻击,而不仅仅是会话劫持。

vBulletin本身并不实际使用“盐”,但在上面的示例中,盐只是添加了有限数量的熵,最好总是找到尽可能多的熵。

例如,在我目前正在用python编写的代码中,我生成了一个用于XSRF保护的散列。下面是我所使用的。

代码语言:javascript
复制
    self.key = sha1(
        self.user.username +
        self.user.password +
        settings.SECRET_KEY +
        strftime("%a, %d %b %Y %H:%M:%S +0000", gmtime())
    ).hexdigest()

它接受用户的用户名和密码、当前时间和一个预设的盐来生成它。对于攻击者来说,由于盐和时间的原因,这将很难生成(但是,请注意,这只是因为它一旦使用就会变得安全,随着时间的推移,如果它不变,那么对于特定用户来说,破解它不会花太多时间)

票数 7
EN

Stack Overflow用户

发布于 2009-03-05 21:50:15

如果我理解正确的话,您想防止会话被猜测会话I的远程攻击者劫持吗?

如果不是这样,那么您就严重超出了您的能力范围--可以窥探流量的攻击者也可以模仿用户代理,而获得对您会话存储的访问权限的攻击者无论如何都会控制您。

如果您存储用户代理字符串以“锁定”到当前用户代理的会话,那么实际上没有必要对其进行散列-对完整的用户代理字符串进行字符串比较会更快(然后进行散列,然后进行比较),并且在存储方面不会显著增加开销。

我不认为存储用户代理可以提供足够的区别--更好的做法是在会话开始时生成一个更大的ID (具有更多的位)(可能是sha1当前时间戳+用户名+用户代理+其他东西),然后将其存储在cookie和会话中,并在每个额外的请求中匹配它。这不会改变攻击向量太多(你仍然需要猜测一些数字),但它很容易通过大量增加攻击的难度来显著增加成功攻击所需的比特数。

更新:

其他答案顺便提到了一些关于加盐哈希的重要内容:仅当您希望攻击者获得对您存储的哈希的访问权限,而不是您的代码,然后以某种方式利用它来利用攻击时,加盐哈希才有意义。

这对于存储了很长时间的密码很有意义,通常存储在一个众所周知的位置,并且由难以定位的代码使用。

这对您的用例没有意义,因为:

  1. 信息只有在会话进行中(在超时之前)才是可行的。在这之后的几个小时内-即使他们获得了存储空间并解码了所有内容-会话也无法被劫持,因为它已经结束。
  2. 通常,如果攻击者能够及时访问您的会话存储空间,他们就可以访问您的纯文本PHP代码,并可以看到您的盐。
  3. 除非您将会话存储在完全不合理的位置(如S3存储桶),否则哈希窃取攻击发生的可能性比许多其他攻击要小得多,其他攻击将非常有用。

简而言之:不要浪费时间编写会话验证代码- PHP内置的会话管理已经足够安全了。

票数 4
EN

Stack Overflow用户

发布于 2009-08-22 02:37:18

如果您在自己的服务器上,加密会话变量是没有意义的,因为它们不会离开服务器。有关更多信息,请参阅 answer to What do I need to store in the php session when user logged in?。如果您在共享服务器中,则可能需要加密除会话ID之外的每个会话变量,因为它们存储在临时文件中,所有邻居都在使用相同的web服务器可读取这些临时文件。

无论如何,如果你真的担心安全性,你最好使用你自己的(虚拟的或非虚拟的)服务器,所以危险只会来自你的服务器之外。

以下是会话风险的一些示例:

  • 您的服务器将在URL中发送会话ID,而您的用户将通过一个链接访问badguys.com,他们将在服务器变量中获取referer (完整的URL,包括您的会话ID)、浏览器和用户的IP地址。如果你没有检查IP,或者你的用户使用开放代理,他们只需要安装相同版本的浏览器,粘贴网址,然后就完成了。
  • 用户转到公共PC,登录,然后在没有关闭会话的情况下离开(嘿,他毕竟是人)。下一个人打开浏览器,查看历史记录,找到一个打开的会话。讨厌,

所以,根据我通常的偏好,你可以采取一些措施:

PHP

  • 不发送会话ID;在中启用session.use_only_cookies。缺点:用户需要启用cookies。
    • 关于危险操作(更改密码,下单...),再次要求用户输入密码。你也可以定期这样做。缺点:很烦人。
    • 超时会话速度快。缺点:在大多数网站中,这会迫使用户经常登录,这会让他们感到恼火。
    • 使用SSL (避免“中间人”攻击的唯一方法)。缺点:速度慢。愚蠢的浏览器消息。需要安全套接字层对server.
    • Check的IP。缺点:对使用公共代理的访问者无效。讨厌动态IP。
    • 检查用户代理(浏览器)。缺点:几乎没有用,UA很容易获得,并且对imitate.

    来说微不足道

(我理所当然地认为您已经为PHP配置了最大的安全性)。

一些更极端的措施:

  • 维护服务器和浏览器之间的永久连接,例如使用Java applet。没有连接,没有会话。缺点:用户需要Java、ActiveX或任何你使用的语言。使用浏览器关闭会话(这可能很好)。在速度非常慢的连接上不起作用。服务器上的负载较高。你需要打开端口,有一个专门的服务器用于applet。
  • 相同,但是使用异步请求(例如AJAX)来非常频繁地刷新会话,并且超时非常短。或者刷新隐藏的IFRAME。缺点:用户需要JavaScript。在速度非常慢的连接上不起作用。服务器上的负载更高。
  • 相同,但会重新加载整个页面。缺点:用户需要JavaScript。在阅读页面时自动重新加载是非常恼人的。

在某些特殊情况下,您可以忘记会话,转而使用Apache身份验证。最简单的解决方案,但有很多限制。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/616545

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档