<form action="/Home/Test" method="post">
<input name="__RequestVerificationToken" type="hidden"
value="6fGBtLZmVBZ59oUad1Fr33BuPxANKY9q3Srr5y[...]" />
<input type="submit" value="Submit" />
</form>
由于恶意页面由于同源策略而无法读取用户的令牌,因此防伪令牌有效。 (同源策略 阻止两个不同站点上托管的文档访问彼此的内容。因此,在前面的示例中,恶意页面可以将请求发送到 example.com,但它无法读取 response.)
若要防止 CSRF 攻击,请使用任何身份验证协议的防伪令牌,浏览器会在用户登录后以无提示方式发送凭据。 这包括基于 Cookie 的身份验证协议,例如表单身份验证,以及基本身份验证和摘要式身份验证等协议。
对于 POST、PUT、DELETE) 的任何非安全 (方法,应要求使用防伪令牌。 此外,请确保安全方法 (GET,HEAD) 没有任何副作用。 此外,如果启用跨域支持(如 CORS 或 JSONP),则甚至 GET 等安全方法可能容易受到 CSRF 攻击的影响,从而允许攻击者读取潜在的敏感数据。
ASP.NET MVC 中的防伪令牌
若要将反伪造令牌添加到 Razor 页面,请使用 HtmlHelper.AntiForgeryToken 帮助程序方法:
@using (Html.BeginForm("Manage", "Account")) {
@Html.AntiForgeryToken()
此方法添加隐藏的窗体字段,并设置 Cookie 令牌。
反 CSRF 和 AJAX
表单令牌可能是 AJAX 请求的问题,因为 AJAX 请求可能会发送 JSON 数据,而不是 HTML 表单数据。 一种解决方法是在自定义 HTTP 标头中发送令牌。 以下代码使用 Razor 语法生成令牌,然后将令牌添加到 AJAX 请求。 令牌通过调用 AntiForgery.GetTokens 在服务器上生成。
<script>
@functions{
public string TokenHeaderValue()
string cookieToken, formToken;
AntiForgery.GetTokens(null, out cookieToken, out formToken);
return cookieToken + ":" + formToken;
$.ajax("api/values", {
type: "post",
contentType: "application/json",
data: { }, // JSON data goes here
dataType: "json",
headers: {
'RequestVerificationToken': '@TokenHeaderValue()'
</script>
处理请求时,请从请求标头中提取令牌。 然后调用 AntiForgery.Validate 方法来验证令牌。 如果令牌无效, Validate 方法将引发异常。
void ValidateRequestHeader(HttpRequestMessage request)
string cookieToken = "";
string formToken = "";
IEnumerable<string> tokenHeaders;
if (request.Headers.TryGetValues("RequestVerificationToken", out tokenHeaders))
string[] tokens = tokenHeaders.First().Split(':');
if (tokens.Length == 2)
cookieToken = tokens[0].Trim();
formToken = tokens[1].Trim();
AntiForgery.Validate(cookieToken, formToken);