每个请求都会更改AntiForgeryToken

9
我正在使用AntiForgeryToken辅助方法。据我了解,防伪标记是基于会话的,因此每个用户都有相同的令牌,但另一个用户将具有不同的令牌(前提是您对所有表单使用相同的盐)。我的“问题”是,AntiForgeryToken为相同的用户使用相同的盐生成不同的令牌。例如... 控制器
public ActionResult Test()
{
    return View();
}

视图

@using (Html.BeginForm())
{
    @Html.AntiForgeryToken("Salty!")
}

Output Request #1

<input name="__RequestVerificationToken" type="hidden" value="K1sijFuYvyGUJjGg33OnLjJaU3tFpGFDutRt9TOFSkZ6FcrhJMMQPnOqjIHuTwBXs/sPBXEiE+1qyV9l63nnSO161b+OtLbaBoPC7K3/7wxtnuSY+N0o/fqBgVoDyac4dNVp+OvanKBSrHINKfc3WEg9269BHOJNzFowC6Aeac/afAGTGrBypxUHfqrKVowD" />

Output Request #2

<input name="__RequestVerificationToken" type="hidden" value="mOpP6LMQXnCmjr5/Wdtnhguh3PyZxWj7GWf8LYzZXPKcJBBT+DbAHvynquSD65O0DBw1RKR7DxCNg372ukftCOWms+o75CraMyFMnvjGk7RU+znIQm05eRQvr5H6d/MDyn+0DWm3jLnMBM9GplsgMRqbdAHzSe69/cS2x9A4X/9jFTZQHUWXXHUr0xewF8Rk" />

使用相同的盐值生成的密钥在同一会话中是不同的。我是否对CSRF保护有基本的误解?还是这是一个新功能?

1个回答

7
反 XSRF 令牌的作用是将相同随机值加密到会话 cookie 和表单中。只有在您从生成的表单中进行提交时,才会提交会话 cookie。
这种方法也适用于服务器群集(在负载均衡场景中),其中所有服务器共享加密密钥。仅通过比较来自已发布的表单数据和已发布的会话 cookie 的解密值来验证。这被称为双重提交 cookie方法。
因此,每个请求获得不同的值是很正常的。这篇文章介绍了 ASP.NET MVC XSRF 令牌。

那么当发出新的令牌时,它会更改服务器上的会话数据吗?我的所有cookie值都保持不变。我以为__RequestVerificationToken_Lw__ cookie值会改变。 - Stefan Bossbaly
不,服务器在客户端上设置cookie。客户端在发布时会两次发送相同的值。一次编码在表单数据中,另一次在cookie中(cookie在POST时传输到服务器)。服务器只知道加密密钥。为了防止XSRF,它不会存储其他任何东西。 - m0sa
有没有理由不将令牌存储在会话中,而不将其发送给客户端?类似于:AntiForgery.GetTokens(null, out cookieToken, out formToken); return cookieToken + ":" + formToken; 然后只需将其存储在会话中即可。 - Jack Marchetti
@Jack 这种方法不需要服务器状态。即使你将其保存在用户会话中,你仍然需要将其与已发布的表单值进行比较,以确保请求确实来自于您的站点。否则,任何网站(例如在另一个标签页中)都可以在用户会话中向您的站点发出调用,而用户并不知情。他只需要登录并访问一个恶意站点。 - m0sa
这是否意味着在同一会话中,隐藏字段中的__RequestVerificationToken将在每个请求中更改,而cookie中的相同值将保持不变。在我们的QA环境中,当我们导航到其他页面时,隐藏字段中的令牌未更改。获取隐藏字段中相同值的问题可能是什么? - Joy George Kunjikkuru

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接