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