代码之家  ›  专栏  ›  技术社区  ›  Henrik Paul

关于签名cookie而不是会话的提示

  •  12
  • Henrik Paul  · 技术社区  · 17 年前

    我正在考虑放弃PHP $_SESSION (即服务器端会话处理,添加一些语言不可知的味道)并使用签名的cookie,因为我听过很多关于它们的好消息(Flickr使用它们,所以它们对我来说也应该足够好)。

    我了解该技术的基本上下文:可以自由地使用cookie将键值对从客户机传递到服务器,并对它们进行签名以确保这些值不会被篡改。

    但是,执行签名部分的好方法是什么?另外,由于流量可能是HTTP,在处理cookie窃取和/或篡改时,有没有一种好的方法可以使用此方法发送敏感数据(如用户密码)?

    3 回复  |  直到 8 年前
        1
  •  23
  •   community wiki 8 revs Paul Dixon    14 年前

    何苦?

    我不会对敏感数据使用这种技术。但是,它与常规会话结合使用是非常有用的——您可以为客户机提供一个具有常规会话ID的cookie,还可以在每个页面上包含应用程序需要的所有键/值对。这样,您就可以避免为每个页面请求访问会话存储。

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

    考虑到这一点,接下来……

    用哈希签名数据

    如果数据不敏感,可以使用 sha1 由键/值对和共享秘密组合而成的哈希。例如

    $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提供一个只允许使用一次的令牌值。 Here's a good article 在那个技术上。

    您还可以考虑将客户机IP包含在签名的cookie中,如果它与呈现cookie的IP不匹配,您可以让他们重新登录。这提供了更多的保护,但不适用于那些明显IP地址不断变化的人。您可以将其作为可选功能,并为用户提供退出的方法。只是一个懒散的想法,我还没有看到它在实践中完成:)

    有关解释会话盗窃、劫持和固定的好文章,请参阅 Sessions and Cookies 它还提供了一些可以尝试的技术,例如使用用户代理头作为附加签名。

        2
  •  15
  •   Riking    9 年前

    我做的 CookieStorage 正是为了这个目的。所有存储的值都通过ripemd160散列(并随时间变化)与您的私钥安全签名,并且可以选择使用rijndael256加密。

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

    Signed example .
    Encrypted example .

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

        3
  •  0
  •   Nadav    8 年前

    用PHP签名的cookie

    这个问题的其他答案有点过时。php 5.2添加了 httponly 参数 setcookie 函数,有效地添加本机签名cookie支持。根据 塞特饼干 功能 httponly parameter documentation :

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

    将此参数设置为true还将禁用使用其他基于浏览器的工具(如chrome的devtools)编辑此cookie的功能。为了使签名的cookie更加安全,我强烈建议缩小其使用的路径或域范围。您可以使用 path domain 参数。当然,使用 secure 参数,如果您的网站正在通过https加载。结果将是这样一行:

    setcookie('signedCookie','uneditable value here', 0, '/', 'www.example.com', TRUE , TRUE);
    

    为什么要使用签名的cookie?

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