将密码存储在 cookie 中是不是安全?
Posted
技术标签:
【中文标题】将密码存储在 cookie 中是不是安全?【英文标题】:Is it secure to store passwords in cookies?将密码存储在 cookie 中是否安全? 【发布时间】:2011-01-07 04:57:03 【问题描述】:我的 Web 应用程序的主页有一个 RememberMe 复选框。如果用户检查它,我会将电子邮件 ID 和密码存储在 cookie 中。这是我的代码:
if (this.ChkRememberme != null && this.ChkRememberme.Checked == true)
HttpCookie cookie = new HttpCookie(TxtUserName.Text, TxtPassword.Text);
cookie.Expires.AddYears(1);
Response.Cookies.Add(cookie);
我想知道的是:
将密码存储在 cookie 中是否安全? 做同样事情的正确方法是什么? 设置 Cookie 时间的最佳做法是什么?【问题讨论】:
让 FormsAuthentication 解决这个问题! FormsAuthentication.SetAuthCookie(username, true); 【参考方案1】:将密码存储在 cookie 中并不安全,因为它们以纯文本形式提供。
Cookie Central. 是查找有关 cookie 的一些答案的好地方@ 对于会员资格,通常使用带有长字符串的 cookie,称为“令牌”,当您提供您的用户名和密码时,它会从网站发出。有关该过程的更多信息,您可以在此article 中找到。 在 ASP.NET 中使用表单身份验证时,您可以像这样设置身份验证 cookie:
FormsAuthentication.SetAuthCookie(userName, isPersistanceCookie);
第二个参数用于“记住我”功能 - 如果为 true,它将创建持久性 cookie,这些 cookie 在您离开网站后将持续存在。您还可以像这样以编程方式操作 cookie:
HttpCookie authCookie =
HttpContext.Current.Request.Cookies[FormsAuthentication.FormsCookieName];
【讨论】:
确实如此。将密码存储在任何地方都不安全。只存储散列版本并对其进行检查。 这里你甚至不需要散列版本(并避免它,因为它有其自身的风险,例如缺乏盐)。与用户 ID 没有数学关系的任意令牌就足够了 - 唯一了解令牌的一方是您的登录服务,它通过数据库查找来检查令牌。 仅供参考,该文章链接 (jaspan.com/improved_persistent_login_cookie_best_practice) 现在被 403 禁止。这是 The Wayback Machine 的一种形式(例如,它 2015 年的最后一张快照):web.archive.org/web/20151115230100/http://jaspan.com/…【参考方案2】:不!不要将密码存储在 cookie 中!
在 ASP.NET 中,使用
FormsAuthentication.SetAuthCookie(username, true);
第二个参数的值决定了 cookie 是否是持久的(记住我复选框的值)。
【讨论】:
【参考方案3】:不,不是远程安全的。您无法保证 cookie 不会以纯文本形式存储(事实上,大多数实现确实将它们存储为纯文本形式)。
请注意,“记住我”本质上是不安全的,因为任何拦截 cookie 的人都可以访问应用程序。但是暴露用户的密码会使它在不安全的阶梯上更进一步。 :-) 如果他们发现的话,可能会让用户非常生气。
我使用了一个加密的 cookie 字符串,它结合了用户的帐户名称和一个令牌,该令牌与用户帐户没有(其他)方式关联,除了在我的服务器上的一个表中。当用户返回站点时,我们解密 cookie 并查看该令牌是否实际上与该帐户相关联。令牌(以及因此的 cookie)会更改每次自动登录,并使用于该自动登录的令牌无效。 (令牌和帐户之间存在多对一的关系,以允许从多个位置自动登录。您可以根据需要对其进行限制。)如果在 X 天内未使用令牌,则会超时。 (这不仅是通过限制 cookie 的持续时间来完成的;它也是在服务器端完成的。)我还添加了一些其他的东西来让尝试的人的生活变得有点困难bit解码 cookie(已成功解密)或使用偷来的 cookie(不需要解密),但没有必要过度使用(同样,“记住我”本质上是不安全的)。
我在一个不需要强大安全性(显然)并且拥有大量动态 IP 客户端的站点上使用它,因此我不会尝试将其锁定到 IP。但即使将其锁定到 IP 也不能保证其安全性,它只会稍微减少攻击面。
您可能想知道为什么我的 cookie 中有用户名。出于直接“记住我”的目的,我不建议将它放在那里,即使它是加密的(毕竟,它是用户名+密码系统中身份验证对的一半)。当我在提醒自己我们是如何为这个问题做这个时查看格式时,我在我们的 cookie 中发现它有点惊讶;但后来我看到 cmets 解释了它为什么在那里,还有一些与“记住我”无关的原因(事后看来,不一定是有说服力的原因,而是原因)。
最后一点,“记住我”本质上是不安全的事实是网站日志非常重要的众多原因之一,也是为什么在允许更改重要帐户信息的过程中需要重新验证密码(以使窃取 cookie 的人更难获得帐户的所有权)。
【讨论】:
每次登录都会更改的令牌将禁止从不同位置(“家”和“工作”)或不同浏览器自动登录到同一帐户。 @Hans:仅当您只允许每个帐户使用一个令牌时。如果您允许令牌和用户帐户之间存在多对一关系(我这样做,通过令牌表),则用户可以激活多个自动登录。我将更新答案以使其更清晰并提及超时。【参考方案4】:这是你永远不应该做的,因为很容易改变 cookie 的值并将其发送回服务器。即使在 cookie 中存储“用户登录为 'naivists'”也是错误的,因为我可以将其更改为“用户登录为 'Pandiya Chendur'”。
您可以在 cookie 中执行的操作是将信息提供给客户端,即使更改了这些信息,对服务器也没有意义。例如 - 最喜欢的颜色、首页布局等。
您可以给他们存储在 cookie 中的会话 ID,因为如果他们将值更改为其他值(除非他们知道另一个会话的有效会话 ID),他们无法为自己做任何更好的事情。
微软的MSDNsays about using cookies:
cookie 的安全问题是 类似于从中获取数据的那些 客户端。在您的应用程序中, cookie 是用户输入的另一种形式 并因此受到审查 和欺骗。一个用户至少可以 查看您存储在 cookie,因为 cookie 可用 在用户自己的计算机上。用户 也可以在之前更改cookie 浏览器将其发送给您。
您不应该存储敏感数据 在 cookie 中,例如用户名, 密码、信用卡号码等 在。不要在 cookie 中放任何东西 那不应该在一个人的手中 用户或某人可能以某种方式 偷饼干。
同样,要怀疑 您从 cookie 中获得的信息。 不要假设数据是 和你写出来的一样;使用 使用 cookie 时的相同保护措施 您将使用的数据的值 用户已键入网页。这 本主题前面的示例显示 对 cookie 的内容进行 html 编码 在页面中显示值之前, 就像在显示任何内容之前一样 您从用户那里获得的信息。
Cookies 在浏览器和浏览器之间发送 服务器作为纯文本,任何人 可以拦截你的网络流量可以 阅读饼干。你可以设置一个cookie 导致 cookie 的属性 仅在连接时传输 使用安全套接字层 (SSL)。 SSL 不保护 cookie 被阅读或操纵 在用户的计算机上,但它确实 防止cookie被读取 在运输过程中,因为 cookie 是 加密。有关详细信息,请参阅 Web 的基本安全实践 应用程序。
【讨论】:
【参考方案5】:如果您在传输任何安全信息时应使用 SSL,则可以避免第三方监听您的网络流量。无论将用户凭据存储在 cookie 中,这将是相同的问题,因为当他们登录时,您无论如何都会将他们的用户名和密码发送到服务器,我假设服务器对其进行哈希处理并将其与您为该用户拥有的哈希密码进行比较。
由于跨域,其他域将永远无法读取您的 cookie,因此这不是问题。
因此,如果您想称其为唯一的“安全漏洞”,那就是如果有人物理上可以访问他们的计算机。如果发生这种情况,他们很可能会从那个人那里得到任何想要的信息。当 chrome auto 为您填写登录表单时,您如何解释,这安全吗?我确定他们不会以纯文本形式存储它,但这并不重要。如果您转到 chrome 自动填充的页面,您只需将密码从表单中复制出来,然后查看您现在是否拥有该人的密码。
这真的取决于您需要它有多“安全”。我同意使用过期作为令牌加密用户信息是验证服务调用的最佳方式,它提供了灵活性。我只是没有看到将登录凭据存储在 cookie 中的问题。
【讨论】:
我认为这个答案被否决了,因为这个问题有 C# 标签并且它吸引了对 HTTP 协议知识非常低的人。从技术上讲,明文密码和作为 cookie 的密码在某种程度上比会话更安全,因为使用某些东西作为会话或加密密码实际上是在添加更多进入系统的方式。【参考方案6】:将密码存储在 cookie 中并不安全,因为它们以纯文本形式提供。 但如果您的首选标准是这样做或有任何用户要求,您可以通过加密字符串来做到这一点。这样就足够安全了。
但不推荐,
【讨论】:
【参考方案7】:我认为您需要使用用户名和从 Windows Identity 获得的加密身份验证字符串创建一个令牌。无需在 cookie 上存储密码。我们的应用程序存储了用户名和经过身份验证的字符串
【讨论】:
【参考方案8】:顺便说一句,存储密码在任何地方都不是安全的,无论是客户端还是服务器端。
你不需要这样做。
【讨论】:
【参考方案9】:Branislav 说了什么,然后……
除了不将敏感数据放入您的 cookie 之外,您还应该通过在 web.config 中至少放置以下内容来保护它们:
<httpCookies httpOnlyCookies="true" />
更多详情见:How exactly do you configure httpOnlyCookies in ASP.NET?
【讨论】:
【参考方案10】:它根本不安全。 Cookies存储在客户端计算机中,可以被篡改。
【讨论】:
以上是关于将密码存储在 cookie 中是不是安全?的主要内容,如果未能解决你的问题,请参考以下文章
将 WebAPI JWT 访问令牌作为加密的 FormsAuthenticationTicket 存储在 Response.Cookies 中是不是安全(在 asp.net mvc 中)