69

我的 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 时间的最佳做法是什么?
4

10 回答 10

65

将密码存储在 cookie 中并不安全,因为它们以纯文本形式提供。

查找有关 cookie 的一些答案的好地方是Cookie Central。当您提供您的用户名和密码时,通常会使用一个带有名为“令牌”的长字符串的 cookie,该 cookie 从网站发出。您可以在本文中找到有关该过程的更多信息。在 ASP.NET 中使用表单身份验证时,您可以像这样设置身份验证 cookie:

FormsAuthentication.SetAuthCookie(userName, isPersistanceCookie);

第二个参数用于“记住我”功能 - 如果为 true,它将创建持久性 cookie,这些 cookie 在您离开站点后将持续存在。您还可以像这样以编程方式操作 cookie:

HttpCookie authCookie =
  HttpContext.Current.Request.Cookies[FormsAuthentication.FormsCookieName];
于 2010-01-20T09:51:59.383 回答
27

不!不要将密码存储在 cookie 中!

在 ASP.NET 中,使用

FormsAuthentication.SetAuthCookie(username, true);

第二个参数的值确定 cookie 是否是持久的(记住我复选框的值)。

于 2010-01-20T09:59:10.613 回答
22

不,不是远程安全的。您无法保证 cookie 不会以纯文本形式存储(事实上,大多数实现将它们存储为纯文本形式)。

请注意,“记住我”本质上是不安全的,因为任何拦截 cookie 的人都可以访问应用程序。但是暴露用户的密码会使它在不安全的阶梯上更进一步。:-) 如果他们发现的话,可能会让用户非常生气。

我使用了一个加密的 cookie 字符串,它结合了用户的帐户名称和一个令牌,该令牌与用户帐户没有(其他)方式关联,除了在我的服务器上的一个表中。当用户返回站点时,我们解密 cookie 并查看该令牌是否实际上与该帐户相关联。令牌(以及因此的 cookie)会更改每次自动登录,并使用于该自动登录的令牌无效。(令牌和帐户之间存在多对一的关系,以允许从多个位置自动登录。您可以根据需要对其进行限制。)如果在 X 天内未使用令牌,则会超时。(这不仅是通过限制 cookie 的持续时间来完成的;它也是在服务器端完成的。)还有一些其他的东西我放在那里让生活变得有点对于试图解码 cookie(已成功解密)或使用偷来的 cookie(不需要解密)的人来说,这是很困难的,但是过度杀伤是没有意义的(同样,“记住我”本质上是不安全的)。

我在一个不需要强大安全性(显然)并且具有大量动态IP客户端的站点上使用它,因此我不会尝试将其锁定到IP。但即使将其锁定到 IP 也不能保证其安全性,它只会稍微减少攻击面。

您可能想知道为什么我的 cookie 中有用户名。出于直接“记住我”的目的,我不建议将它放在那里,即使它是加密的(毕竟,它是用户名+密码系统中身份验证对的一半)。当我在提醒自己我们是如何为这个问题做这个时查看格式时,我在我们的 cookie 中发现它有点惊讶;但是后来我看到评论解释了它为什么在那里,并且有一些与“记住我”无关的原因(事后看来,不一定是有说服力的原因,而是原因)。

最后一点,“记住我”本质上是不安全的这一事实是站点日志非常重要的众多原因之一,也是为什么在允许更改重要帐户信息的过程中需要重新验证密码(以使其更难有人窃取了 cookie 以获取帐户的所有权)。

于 2010-01-20T10:06:38.597 回答
12

这是您永远不应该做的事情,因为更改 cookie 的值并将其发送回服务器非常容易。即使在 cookie 中存储“用户登录为 'naivists'”也是错误的,因为我可以将其更改为“用户登录为 'Pandiya Chendur'”。

您可以在 cookie 中做的就是向客户端提供信息,即使更改了这些信息,对服务器也没有意义。例如 - 最喜欢的颜色、首页布局等。

您可以为他们提供存储在 cookie 中的会话 ID,因为如果他们将值更改为其他值(除非他们知道来自另一个会话的有效会话 ID),他们无法为自己做出任何更好的事情。

Microsoft 的 MSDN关于使用 cookie 的说明

cookie 的安全问题类似于从客户端获取数据的问题。在您的应用程序中,cookie 是另一种形式的用户输入,因此会受到检查和欺骗。用户至少可以看到您存储在 cookie 中的数据,因为 cookie 在用户自己的计算机上可用。用户还可以在浏览器发送给您之前更改 cookie。

您不应将敏感数据存储在 cookie 中,例如用户名、密码、信用卡号等。不要在 cookie 中放入不应该由用户或可能以某种方式窃取 cookie 的人手中的任何内容。

同样,对您从 cookie 中获得的信息保持怀疑。不要假设数据与您写出时的数据相同;在处理 cookie 值时使用与处理用户在网页中键入的数据相同的保护措施。本主题前面的示例展示了在页面中显示值之前对 cookie 的内容进行 HTML 编码,就像在显示从用户处获得的任何信息之前一样。

Cookie 在浏览器和服务器之间以纯文本形式发送,任何可以拦截您的 Web 流量的人都可以读取 Cookie。您可以设置一个 cookie 属性,该属性导致仅当连接使用安全套接字层 (SSL) 时才传输 cookie。SSL 不会保护 cookie 在用户计算机上不被读取或操纵,但它会阻止 cookie 在传输过程中被读取,因为 cookie 是加密的。有关详细信息,请参阅 Web 应用程序的基本安全实践。

于 2010-01-20T09:56:00.867 回答
5
  • 如果您使用 SSL,如果您正在传输任何安全信息,您应该这样做,这可以消除第三方监听您的网络流量。无论将用户凭据存储在 cookie 中,这将是相同的问题,因为当他们登录时,您无论如何都会将他们的用户名和密码发送到服务器,我假设服务器对其进行哈希处理并将其与您为该用户拥有的哈希密码进行比较。

  • 由于跨域,其他域将永远无法读取您的 cookie,因此这不是问题。

  • 因此,如果您想称其为唯一的“安全漏洞”,那就是如果有人物理上可以访问他们的计算机。如果发生这种情况,他们很可能会从那个人那里得到任何想要的信息。当 chrome auto 为您填写登录表单时,您如何解释,这安全吗?我确定他们不会以纯文本形式存储它,但这并不重要。如果您转到 chrome 自动填充的页面,您只需将密码从表单中复制出来,然后查看您现在是否拥有该人的密码。

  • 这真的取决于你需要它有多“安全”。我同意使用过期作为令牌加密用户信息是验证服务调用的最佳方式,它提供了灵活性。我只是没有看到将登录凭据存储在 cookie 中的问题。

于 2015-07-29T12:10:22.470 回答
3

将密码存储在 cookie 中并不安全,因为它们以纯文本形式提供。但如果您的首选标准是这样做或有任何用户要求,您可以通过加密字符串来做到这一点。这可以使这足够安全。

但不推荐,

于 2010-01-20T10:35:58.720 回答
3

我认为您需要使用用户名和从 Windows 身份获得的加密身份验证字符串创建一个令牌。无需在 cookie 上存储密码。我们有我们的应用程序,它存储了用户名和经过身份验证的字符串

于 2010-01-20T10:45:46.557 回答
3

顺便说一句,存储密码在客户端和服务器端都不是安全的。

你不需要这样做。

于 2010-01-30T15:42:38.850 回答
2

布拉尼斯拉夫所说的,以及...

除了不将敏感数据放入您的 cookie 之外,您还应该通过在 web.config 中至少放置以下内容来保护它们:

<httpCookies httpOnlyCookies="true" />

有关详细信息,请参阅:您如何在 ASP.NET 中准确配置 httpOnlyCookies?

于 2013-04-09T20:05:30.750 回答
1

它根本不安全。Cookie 存储在客户端计算机中,可以被篡改。

于 2010-01-20T10:00:56.473 回答