有没有一种方法可以防止cookie被盗取?

8
在Web 2.0应用程序中,许多用户通常希望保持登录状态(“记住我”标志),而他们的Cookie可能会访问非常私密的数据。有没有办法防止窃取Cookie的人 - 直接从计算机或通过嗅探 - 使用Cookie来访问用户的数据?始终使用HTTPS不是一个选择。谢谢,Bernd。[编辑]将IP地址连接到Cookie也不是一个选择。
7个回答

8
KISS -- 只需使用会话(session),这样你就使用了一个由你选择的服务器端脚本语言自动创建的ID,这已经足够难以猜测。然后,如果它被盗,将访问者的IP地址和用户代理存储在会话中(确保从不输出),并且只有当已存储的IP地址和用户代理与远程客户端找到的匹配时,才认为该会话是有效的。
在这种情况下,攻击者必须完成以下三件事:
1.窃取受害者的Cookie 2.欺骗正确的IP地址 3.欺骗正确的用户代理
此外,确保攻击者不知道他/她需要做哪些事情才能正确接管受害者的会话也是有帮助的。例如:他们可能认为只需要Cookie,然后失败...并且必须通过漫长的试错过程找出其他所有内容。通过这种方式,您可以通过混淆和困难来提高安全性,这取决于攻击者的技能和他/她对系统的现有知识。

1
这似乎不是很安全。有可能通过向用户的浏览器注入代码或拦截明文HTTP来以编程方式获取所有这些参数。 - Lawrence Weru
我认为如果用户使用移动设备通过4G网络浏览网站,该方法可能无法正常工作,因为IP地址会不断变化。 - Mohamad Hamouday

6
Bernd - 任何基于标准HTTP的东西都存在明文传输的问题,任何人都可以伪造。IP欺骗比仅仅窃取cookie更具挑战性,因此将其绑定到IP可能是人们的选择。就像你说的那样,在高度动态的环境中这种方式并不奏效。
我能想到的唯一安全的方法是使用HTTPS来放置和验证“永久”cookie,然后在同一个HTTPS会话中放置(一个)短期的会话cookie。其余通信可以通过常规HTTP完成,使用会话cookie进行身份认证。
这样,支持加密的资源更少(仅握手),永久cookie不会被暴露,只在加密传输时传送,而窃取会话cookie只会带来有限的风险,因为该cookie很快会过期。
以上所有内容需要注意的是- 不要让用户在包含真正敏感数据的网站上点击“记住我”!这就是银行不这样做的原因。
希望对你有所帮助。

这个用例如何应用到 F5 LB 上?假设 SSL 在 BigIP 上终止。流量传输到后端服务器是明文的,通过 HTTP 进行。假设 F5 LB 配置了 Cookie Persistence。我认为你需要利用 Cookie Hash/iRules 来模拟一次性使用的令牌,这就是你在这里描述的内容。如果攻击者已经破解了 HTTPS(即 MITM),那么在那时可能没有太多可以做的事情,除了规避对 HTTPS 连接的攻击。 - user3621633
IP欺骗如何有帮助?这不会导致响应发送到错误的IP地址,从而使恶意请求无法返回到该请求的发起者吗? - ErikE

3

关于在数据库中存储复杂的cookie id和相关IP,您其实不需要这样做。如果您有一个秘密密钥K,则足以使用K加密用户的IP,并将结果{IP}K作为cookie。只要您的密钥是安全的(并且加密方式没有被破解 - 但如果发生这种情况,我们会有更大的问题),这是安全的。


2
也许使用会话ID和令牌(基于IP、盐和会话ID的哈希值)并在每个请求中重新生成(使用快速哈希算法)是一个好方法?我目前将会话数据存储在数据库中,这意味着每个请求都需要两个查询。它的工作方式如下:
  1. 选择SID和TOK匹配的位置。
  2. 验证基于当前客户端生成的令牌是否与数据库中的令牌匹配。
  3. 将数据反序列化为属性。
  4. 脚本等操作。
  5. 将更新后的数据序列化,重新生成SID/TOK,并更新DB,其中SID/TOK=旧SID和TOK、更新数据和新SID和TOK。将cookie设置为新的SID和TOK。
以这种方式,首先将cookie绑定到我基于令牌的任何内容(在这种情况下是远程地址),如果被盗取并伪造客户端数据,则cookie只对一个请求有用 - 在拦截cookie时,它已经无用了。
我唯一能看到的弱点是,如果攻击者在真正的人进行另一个请求之前成功地抓住cookie、欺骗并使用它。我需要考虑几种解决方法。开销是两个查询和两次生成令牌哈希(一次用于验证,一次用于替换)。

你无法阻止真正的用户在进行另一个请求之前使用 cookie,但是你可以检测到 cookie 的第二次使用并发出警报,知道有些事情不对劲,两个请求中的任何一个都可能是黑客攻击的实例。 - ErikE

1

将一个不常见的ID作为cookie存储到本地服务器数据库中。根据cookie中提供的ID进行服务器端DB查找。确保ID足够复杂,以便不易猜测。将ID映射到用户的IP地址。如果他们的IP地址发生变化,则强制他们重新登录并创建新的ID。

再次阅读,听起来像是您想要高水平的安全性,但手脚被绑住了。用户必须有选择保持登录状态,从而增加他/她的风险。您可以从应用程序和服务器的角度实现所有安全性,但如果用户忘记在Tim Horton's(加拿大星巴克)的桌子上留下笔记本电脑,那么这些都没有用。

让用户自行选择是否保持登录状态,并警告他们的信息存在风险。


嗨Kieveli,这对用户来说听起来不太方便。有很多环境下IP地址经常变化,用户不想一遍又一遍地登录,这就是为什么他/她选择了“记住我”的原因。 - Kevin Dente
Cookie只能被特定的域名访问。想一想:如果有人可以窃取cookie,那么这意味着窃贼已经可以访问计算机,如果他可以这样做,他可以打开浏览器并访问该网站。但是,某些攻击是可能的。我建议您按照上述方式进行。 - Loki
1
Loki -- 这是不正确的。Cookies 在互联网上以明文形式发送;如果您使用无线网络,嗅探它们相当容易。 - SquareCog

1

不要让饼干罐子敞开着。

开玩笑的,最好的选择已经被提出 - 将饼干设为一个模糊的ID,并将其与服务器端的IP地址查找绑定。由于您编辑后说无法将其绑定到IP地址,这就只剩下了模糊的ID部分。使用cookie时您的选择是有限的 - 一旦在客户端放置了某些东西,它就成为了风险。


0
Bernd - 你说将IP地址与cookie连接起来不是一个选项,我猜想这是因为用户可能通过DHCP连接,因此每次可能会使用不同的IP地址。您考虑过将cookie绑定到DNS主机名吗?您可以使用私钥加密cookie,并将其存储在用户的计算机上。然后,每当他们进入时,检查cookie,解密它,然后将用户当前的DNS主机名与cookie中的主机名进行比较。如果匹配,则允许登录。如果不匹配,则不允许自动登录。
FYI- 在ASP.Net中,要获取用户计算机的DNS主机名,只需查看
Page.Request.UserHostName

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接