PHP会话+;盐渍剂

PHP会话+;盐渍剂,php,user-agent,salt,session-hijacking,Php,User Agent,Salt,Session Hijacking,在过去的几天里,它一直在我脑海中运行,但我读了一些关于如何使PHP会话更安全的文章。几乎所有这些文章都说,您需要在会话中使用额外的salt保存useragent。大概是这样的: $fingerprint = md5('SECRET-SALT'.$_SERVER['HTTP_USER_AGENT']); md5('SECRET-SALT'.$_SERVER['HTTP_USER_AGENT']) == $_SESSION [ 'fingerprint' ] salt会使攻击者更难劫持会话或其他

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

$fingerprint = md5('SECRET-SALT'.$_SERVER['HTTP_USER_AGENT']);
md5('SECRET-SALT'.$_SERVER['HTTP_USER_AGENT']) == $_SESSION [ 'fingerprint' ]
salt会使攻击者更难劫持会话或其他任何会话。但为什么每次检查时都要添加盐,如下所示:

$fingerprint = md5('SECRET-SALT'.$_SERVER['HTTP_USER_AGENT']);
md5('SECRET-SALT'.$_SERVER['HTTP_USER_AGENT']) == $_SESSION [ 'fingerprint' ]
既然攻击者仍然只需要useragent(这是一组相对较小的不同useragent)和sessionid,那么为什么salt会使它更安全呢

可能是我忽略了一些小东西,但我想不出来,让我发疯了哈哈

谢谢

我也这样做。您还需要包括IP地址


请记住,当客户端的浏览器自动更新时,用户代理会发生更改,您会认为他的会话已被劫持;)

由于指纹存储在服务器端,因此不需要使用盐渍散列。“普通”散列就足以减少数据量。

请记住,如果你这样做,那么如果人们升级浏览器,你就是在强迫他们再次登录。这没关系,但要确保这是你的意图

使用用户的远程地址也不是没有问题。许多人在不同的地方使用同一台计算机。移动设备、在家和工作中使用的笔记本电脑、在Wifi热点使用的笔记本电脑等等。我认为,除非您处理的是高度敏感的信息,如网上银行,否则使用IP地址时,新的IP地址需要登录是个坏主意。是这样吗

你担心什么?外部攻击?或者在共享主机的情况下,有人可以读取您的会话信息

如果是后者,解决方案很简单:只需在会话中不存储任何敏感信息。任何敏感信息都应存储在数据库中

在制作秘密盐的过程中,你需要使用一些不可猜测的东西。我会选择创建用户时创建的随机字符串。如有必要,请在每次会话无效时重新创建它


至于什么能让它更安全,你自己也说过:用户代理字符串有限(少于100个可能覆盖99.99%的用户)。盐只会增加可能性的数量。这就是说,如果你在所有训练中都使用相同的盐,那么使用蛮力发现它只是时间问题。

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

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

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

我建议您添加更多内容,例如,在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地址
他们还必须伪造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()

它使用用户的用户名和密码、当前时间和预设的salt生成此消息。由于salt和时间的原因,攻击者很难生成此消息(尽管如此,请注意,只有当它被使用后才会发生变化,随着时间的推移,如果它没有变化,那么对于某个特定用户来说,破解它不会花费太多时间。)

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

如果不是这样的话,那么你就严重超出了你的能力范围——一个能够窥探流量的攻击者也可以模仿用户代理,而一个能够访问你的会话存储的攻击者无论如何都会抓住你

如果您存储用户代理字符串以将会话“锁定”到当前用户代理,那么散列就没有意义了-对完整的用户代理字符串进行字符串比较更快(然后进行散列,然后进行比较),并且在存储方面不会显着更昂贵

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