ASP.NET MVC Anti Forgery Token不安全

时间:2014-03-19 22:38:04

标签: asp.net asp.net-mvc asp.net-mvc-3 security csrf

在没有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)
  });
}

3 个答案:

答案 0 :(得分:24)

这就是你所拥有的煽动性问题标题。

内置的MVC防伪功能与应用程序配置一样安全。写入Response.Cookies的所有cookie都将自动标记为&#34; secure&#34;如果在Web.config(see MSDN docs)中设置了<httpCookies requireSSL="true" />,则为修饰符。如果设置此开关,MVC的防伪cookie也会出现此行为。

将此功能与您的回复中的setting the HSTS header等其他功能相结合,您实际上可以保证浏览器永远不会通过纯文本频道发送敏感数据。

此外,防伪系统允许在令牌中存储自定义数据,并且您可以在验证令牌时接收回调以验证自定义数据。有关详细信息,请参阅AntiForgeryConfig.AdditionalDataProvider

答案 1 :(得分:9)

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

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

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

答案 2 :(得分:0)

我的选择

a)表格提交被认为是基于

的比较而伪造的
  • __ RequestVerificationToken Cookie &amp;

  • __ RequestVerificationToken表单字段。

这两个值是某种对称匹配,因此不相同。

b)框架永远不能将Cookie标记为默认必须使用安全通道,因为某些应用程序不使用https。

c)__RequestVerificationToken实现是对CSRF&amp;无法帮助有效用户窥探进程内存:p。