ASP.NET MVC Anti Forgery Token不安全

Alw*_*wyn 9 asp.net security asp.net-mvc csrf asp.net-mvc-3

我实际上可以在没有ssl的情况下向服务器发出请求时以纯文本形式看到MVC3框架生成的验证令牌密钥.

此密钥存储在名为:_RequestVerificationToken_Lw__的cookie中

在混合安全环境中,实际上可以在对非ssl站点的初始请求中以明文形式看到此令牌发送到服务器.此令牌在用户会话期间也是静态的.那么当攻击者很容易被盗时,使用这个令牌会有什么用处,因为cookie会以纯文本形式被抛出.

这个cookie不应该标记为安全,永远不会以纯文本形式发送吗?或者至少在每个请求上重新生成,以便安全信息不会泄漏出ssl通道?

我在谈论MVC 3 AntiForgeryWorker类中的这个块

private string GetAntiForgeryTokenAndSetCookie(HttpContextBase httpContext, string salt, string domain, string path)
{
  string forgeryTokenName = AntiForgeryData.GetAntiForgeryTokenName(httpContext.Request.ApplicationPath);
  AntiForgeryData token = (AntiForgeryData) null;
  HttpCookie httpCookie = httpContext.Request.Cookies[forgeryTokenName];
  if (httpCookie != null)
  {
    try
    {
      token = this.Serializer.Deserialize(httpCookie.Value);
    }
    catch (HttpAntiForgeryException ex)
    {
    }
  }
  if (token == null)
  {
    token = AntiForgeryData.NewToken();
    string str = this.Serializer.Serialize(token);
    HttpCookie cookie = new HttpCookie(forgeryTokenName, str)
    {
      HttpOnly = true,
      Domain = domain
    };
    if (!string.IsNullOrEmpty(path))
      cookie.Path = path;
    httpContext.Response.Cookies.Set(cookie); //Ma, Why isn't this marked as "SECURE"
  }
  return this.Serializer.Serialize(new AntiForgeryData(token)
  {
    Salt = salt,
    Username = AntiForgeryData.GetUsername(httpContext.User)
  });
}
Run Code Online (Sandbox Code Playgroud)

Lev*_*evi 25

That's quite the inflammatory question title you have there.

The built-in MVC anti-forgery functionality is as secure as the application is configured to be. All cookies written to Response.Cookies will be automatically marked with the "secure" modifier if <httpCookies requireSSL="true" /> is set in Web.config (see MSDN docs). MVC's anti-forgery cookie also gets this behavior if this switch is set.

Combine this with other functionality like setting the HSTS header in your responses, and you're essentially providing a guarantee that the browser will never send sensitive data over plaintext channels.

Additionally, the anti-forgery system does allow storing custom data in the tokens, and you can receive a callback to verify the custom data when the token is validated. See AntiForgeryConfig.AdditionalDataProvider for more information.

  • 许多年前,SSL曾经很昂贵.这已不再是这种情况.完全SSL站点现在具有与混合安全站点相同的性能特征.不过,您可以设置anti-xsrf cookie的"安全"标志,而无需使用AntiForgeryConfig.RequireSSL属性选择所有内容:请参阅http://msdn.microsoft.com/en-us/library/system.web.helpers .antiforgeryconfig.requiressl(v = vs.111).aspx了解更多信息. (3认同)
  • @Levi,这不是一个全有或全无的提议吗?出于性能原因,我们有一个混合安全站点。我们不打算通过 ssl 发送所有 cookie。只是我们认为“敏感”的那些。这个CSRF符合“敏感”的要求。即使有额外的数据提供者,这也无法避免 cookie 可能通过非安全通道传输的事实,除非您认为我应该自己处理加密。 (2认同)

Nat*_*nSr 9

通过防止CSRF攻击,最佳解决方案是始终使用SSL.没有SSL,是的,nonce - 它被称为 - 容易受到MITM攻击.使用cookie存储nonce时,cookie 必须标记为仅HTTP.这可以防止JavaScript读取cookie.除了cookie之外,您还应该将nonce渲染为<input type="hidden" value="nonce">所有<form>s中的标记.

任何能够访问浏览器本身的人都能够读取该随机数,防止重放攻击的唯一方法是在服务器首次验证后,第一次使用随机数到期.但是,当用户使用后退按钮并使用相同的随机数重新提交请求时,此方法可能会导致糟糕的用户体验.因为您正在使用ASP.NET MVC的内置反CSRF保护机制,所以将其行为更改为仅允许使用一次nonce可能并不容易.(编辑:感谢下面的Levi告诉我,ASP.NET MVC实际上让这很简单)

如果你想更好地控制生成和验证nonce,那么我建议滚动你自己的实现,就像我使用JuniorRoute框架一样.事实上,请随时查看JuniorRoute的源代码,了解我是如何实现它的.Stack Overflow帖子的代码太多了.