有关签名cookie而非会话的提示

时间:2009-02-07 11:34:58

标签: php security session cookies

我正在考虑放弃PHP的$_SESSION(即服务器端会话处理,添加一些语言无关的风格)并使用签名的cookie代替,因为我听到了很多关于它们的好处(Flickr使用他们,所以他们也应该对我也足够好。)

我理解该技术的基本背景:使用cookie自由地将键值对从客户端传递到服务器,并对其进行签名以确保值不被篡改。

但是实施签名部分的好方法是什么?也;由于流量可能是HTTP,是否有一种使用此方法发送敏感数据(例如用户密码)的好方法,同时防止cookie窃取和/或篡改?

3 个答案:

答案 0 :(得分:23)

为什么要这么麻烦?

我不会将此技术用于敏感数据。它可以与常规会话结合使用 - 您可以为客户端提供具有正常会话ID的cookie,但也包括应用程序在每个页面上所需的所有键/值对。这样,您就可以避免为每个页面请求访问会话存储。

您的目标应该是保持数据量非常紧张,因为它会随着每个请求一起发送。

考虑到这一点,直到......

使用哈希

签署数据

如果数据不敏感,您可以使用由键/值对和共享密钥组合而成的sha1哈希对值进行签名。 e.g。

$values=array(
  'user_id'=>1,
  'foo'=>'bar'
);
$secret='MySecretSalt';

$plain="";
foreach($values as $key=>$value)
{
    $plain.=$key.'|'.$value.'|';
}
$plain.=$secret;
$hash=sha1($plain);

现在给客户端一个包含所有值和哈希值的cookie。您可以在呈现cookie时检查哈希值。如果您根据客户端显示的值计算的哈希值与预期的哈希值不匹配,则表示值已被篡改。

加密敏感数据

对于敏感数据,您需要加密值。查看提供大量加密功能的mcrypt扩展程序。

Cookie盗窃

关于cookie窃取,如果您将用户凭据放入cookie并信任它,那么获得该cookie的人可以冒充该用户,直到密码被更改为止。一个好的做法是记住您对用户进行身份验证的方式,并且只有在用户明确登录时才授予某些权限。例如,对于论坛,您可以让某人发帖,但不要更改他们的帐户详细信息,如电子邮件地址。

“自动登录”cookie还有其他技术,包括为这些cookie提供一个令牌值,您只允许使用一次。关于这种技术Here's a good article

您还可以查看在签名cookie中包含客户端IP,如果它与提供cookie的IP不匹配,则会让他们再次登录。这提供了更多保护,但对于明显IP地址不断变化的人不起作用。您可以将其设为可选功能,并为用户提供退出选项的方法。只是一个无所事事的想法,我在实践中没有看到这样做:)

有关解释会话被盗,劫持和录制的好文章,请参阅Sessions and Cookies,其中提供了一些其他技巧,例如使用User-Agent标头作为附加签名。

答案 1 :(得分:16)

我完全为此目的制作了CookieStorage。所有存储的值都通过RIPEMD160散列(并随时间盐化)使用您的私钥进行安全签名,并可选择使用RIJNDAEL256进行加密。

每个值都与时间戳一起存储,时间戳是可检索的。

Signed example
Encrypted example

如果您愿意,可以使用您选择的哈希/加密/解密函数。

答案 2 :(得分:0)

在PHP中签名的Cookie

这个问题的其他答案有点过时了。 PHP 5.2将httponly参数添加到setcookie函数,有效地添加了本机签名的cookie支持。根据{{​​1}}函数httponly parameter documentation

  

"当[设置为]为TRUE时,只能通过HTTP协议访问cookie。这意味着cookie无法通过脚本语言(例如JavaScript)访问。有人建议这种设置可以通过XSS攻击有效地帮助减少身份盗用(尽管并非所有浏览器都支持),但这种说法经常受到质疑"

将此参数设置为true还会禁用使用其他基于浏览器的工具(例如Chrome的DevTools)编辑此Cookie的功能。为了使签名的cookie更加安全,我强烈建议缩小它使用的路径或域。您可以使用setcookiepath参数指定这些参数。当然,如果您的网站是通过HTTPS加载的,那么使用domain参数保护cookie绝对不会受到伤害。结果将是这样的一行:

secure

为什么要使用签名的Cookie?

事实上,有一些特定的情况,其中签名的cookie是有用的,而其他方法,如会话,则不是。例如,让我们假设有问题的网站/应用程序使用负载均衡器来提高性能。现在让我们假设负载均衡器有多个物理服务器,从中提供文件,并且粘性会话选项不可用。在这种情况下,签名cookie几乎是用PHP保存状态的唯一安全方式。