CSRF(Cross-site request forgery)跨站请求伪造,也被称为“One Click Attack”或者Session Riding,通常缩写为CSRF或者XSRF,是一种对网站的恶意利用。尽管听起来像跨站脚本(XSS),但它与XSS非常不同,XSS利用站点内的信任用户,而CSRF则通过伪装成受信任用户的请求来利用受信任的网站。与XSS攻击相比,CSRF攻击往往不大流行(因此对其进行防范的资源也相当稀少)和难以防范,所以被认为比XSS更具危险性。
这幅图已经能够很好地解释了跨站攻击是怎么回事,这样的网站很容易被别人钓鱼,
示例:
创建2个网站
officialsite站点里有个 pay页面
view:
支付
paycontroller:
[HttpPost]
public IActionResult Post(string user, decimal price)
{
return Json(new { ok = true, msg = $"{user}支付成功{price}元" });
}
FakeSite 站点里有个fakepay页面
view:
假的支付
提交的请求并非自己站点 而是上一个站点的接口
- 运行效果
界面 | 运行效果 |
---|---|
点击提交后一样返回了上面网站的请求结果,这样官网就太危险了。 |
那么asp.net core mvc里怎么处理?
CSRF能够成功是因为在同一个浏览器中Cookies是共享的,也就无法通过cookies权限认证和验证来防止。
解决的办法就是:要确保请求是自己的站点发出的就可以了,其他的站点发来的请求阻挡掉。
通过AntiForgeryToken 在页面生成一个Token,发请求的时候把Token带上。处理服务端处理请求的时候需要验证这个Token。而其他站点没有这个token那么也就没法通过验证,就被阻挡了。
- 继续改造上面的demo:
F12看生成的html
支付
controller
[ValidateAntiForgeryToken]
[HttpPost]
public IActionResult Post(string user, decimal price)
{
return Json(new { ok = true, msg = $"{user}支付成功{price}元" });
}
运行后界面一切正常
接下来我们在取运行上一个伪造的站点,什么都不改,提交后就会提示返回400的错误
这样就能搞定了。
以上是表单提交,项目中常用的还是ajax请求,那该如何处理呢
view:
@inject Microsoft.AspNetCore.Antiforgery.IAntiforgery csrf
将ajax请求头里加上token,这样服务端就会校验。
运行结果
配置
这个令牌验证还是需要借助cookie的
配置 在setup里,可以根据需要去添加,比如需要验证的域名
services.AddAntiforgery(options =>
{
options.Cookie = new CookieBuilder { Domain = "company.com" };
});