定义跨站点请求伪造(CSRF)是一种攻击方式,恶意站点向用户当前登录的易受攻击的站点发送请求。 以下是CSRF攻击的示例:
虽然此示例需要用户单击表单按钮,但是恶意页面可以轻松运行自动提交表单的脚本。此外,使用SSL不会阻止CSRF攻击,因为恶意站点可以发送“https://”请求。 通常,针对使用Cookie进行身份验证的网站可能会发生CSRF攻击,因为浏览器会将所有相关的Cookie发送到目标网站。然而,CSRF攻击并不仅限于利用Cookie。例如,Basic和Digest身份验证也很脆弱。用户使用“Basic”或“Digest”身份验证登录后。浏览器自动发送凭证直到会话结束。 防伪令牌(Anti-Forgery Tokens)为了帮助防止CSRF攻击,ASP.NET MVC使用防伪令牌(Anti-Forgery Tokens),也称为请求验证令牌。
以下是具有隐藏表单令牌的HTML表单的示例: <form action="/Home/Test" method="post"> <input name="__RequestVerificationToken" type="hidden" value="6fGBtLZmVBZ59oUad1Fr33BuPxANKY9q3Srr5y[...]" /> <input type="submit" value="Submit" /> </form> 防伪令牌的工作原因是恶意页面无法读取用户的令牌,因为同源策略。(同源策略可以防止两个不同站点上托管的文件访问对方的内容,所以在前面的例子中,恶意页面可以发送请求到,但不能读取响应。) 为了防止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令牌。 Anti-CSRF 和 AJAX表单令牌可能是AJAX请求的一个问题,因为AJAX请求可能会发送JSON数据,而不是HTML表单数据。一个解决方案是将Token发送到自定义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方法来验证令牌。如果令牌无效,该验证方法将引发异常。 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); }
|
|
来自: ThinkTank_引擎 > 《xsrf-csrf》