欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

切记ajax中要带上AntiForgeryToken防止CSRF攻击

程序员文章站 2022-06-09 10:10:17
经常看到在项目中ajax post数据到服务器不加防伪标记,造成csrf攻击 在asp.net mvc里加入防伪标记很简单在表单中加入html.antiforgeryto...

经常看到在项目中ajax post数据到服务器不加防伪标记,造成csrf攻击

在asp.net mvc里加入防伪标记很简单在表单中加入html.antiforgerytoken()即可。

html.antiforgerytoken()会生成一对加密的字符串,分别存放在cookies 和 input 中。

我们在ajax post中也带上antiforgerytoken

@model webapplication1.controllers.person
@{
 viewbag.title = "index";
}
<h2>index</h2>
<form id="form1">
 <div class="form-horizontal">
  <h4>persen</h4>
  <hr />
  @html.validationsummary(true, "", new { @class = "text-danger" })
  <div class="form-group">
   @html.labelfor(model => model.name, htmlattributes: new { @class = "control-label col-md-2" })
   <div class="col-md-10">
    @html.editorfor(model => model.name, new { htmlattributes = new { @class = "form-control" } })
    @html.validationmessagefor(model => model.name, "", new { @class = "text-danger" })
   </div>
  </div>
  <div class="form-group">
   @html.labelfor(model => model.age, htmlattributes: new { @class = "control-label col-md-2" })
   <div class="col-md-10">
    @html.editorfor(model => model.age, new { htmlattributes = new { @class = "form-control" } })
    @html.validationmessagefor(model => model.age, "", new { @class = "text-danger" })
   </div>
  </div>
  <div class="form-group">
   <div class="col-md-offset-2 col-md-10">
    <input type="button" id="save" value="create" class="btn btn-default" />
   </div>
  </div>
 </div>
</form>
<script src="~/scripts/jquery-1.10.2.min.js"></script>
<script src="~/scripts/jquery.validate.min.js"></script>
<script src="~/scripts/jquery.validate.unobtrusive.min.js"></script>
<script type="text/javascript">
 $(function () {
  //var token = $('[name=__requestverificationtoken]');
  //获取防伪标记
  var token = $('@html.antiforgerytoken()').val();
  var headers = {};
  //防伪标记放入headers
  //也可以将防伪标记放入data
  headers["__requestverificationtoken"] = token;
  $("#save").click(function () {
   $.ajax({
    type: 'post',
    url: '/home/index',
    cache: false,
    headers: headers,
    data: { name: "yangwen", age: "1" },
    success: function (data) {
     alert(data)
    },
    error: function () {
     alert("error")
    }
   });
  })
 })
</script>

放在cookies里面的加密字符串

控制器中代码

using system;
using system.collections.generic;
using system.linq;
using system.net;
using system.web;
using system.web.helpers;
using system.web.mvc;
namespace webapplication1.controllers
 {
 public class homecontroller : controller
  {
  public actionresult index()
   {
   return view();
   }
  [httppost]
  [myvalidateantiforgerytoken]
  public actionresult index(person p)
   {
   return json(true, jsonrequestbehavior.allowget);
   }
  }
 public class person
  {
  public string name { get; set; }
  public int age { get; set; }
  }
 public class myvalidateantiforgerytoken : authorizeattribute
  {
  public override void onauthorization(authorizationcontext filtercontext)
   {
   var request = filtercontext.httpcontext.request;
   if (request.httpmethod == webrequestmethods.http.post)
    {  
    if (request.isajaxrequest())
     {
     var antiforgerycookie = request.cookies[antiforgeryconfig.cookiename];
     var cookievalue = antiforgerycookie != null
      ? antiforgerycookie.value
      : null;
     //从cookies 和 headers 中 验证防伪标记
     //这里可以加try-catch
     antiforgery.validate(cookievalue, request.headers["__requestverificationtoken"]);
     }
    else
     {
     new validateantiforgerytokenattribute()
      .onauthorization(filtercontext);
     }
    }
   }
  }
 }

这里注释掉ajax中防伪标记在请求

$("#save").click(function () {
 $.ajax({
  type: 'post',
  url: '/home/index',
  cache: false,
 //  headers: headers,
  data: { name: "yangwen", age: "1" },
  success: function (data) {
   alert(data)
  },
  error: function () {
   alert("error")
  }
 });
})

默认返回500的状态码。

这里修改ajax中的防伪标记

  $(function () {
 //var token = $('[name=__requestverificationtoken]');
 //获取防伪标记
 var token = $('@html.antiforgerytoken()').val();
 var headers = {};
 //防伪标记放入headers
 //也可以将防伪标记放入data
 headers["__requestverificationtoken"] = token+11111111111111111111111111111111111;
 $("#save").click(function () {
  $.ajax({
   type: 'post',
   url: '/home/index',
   cache: false,
    headers: headers,
   data: { name: "yangwen", age: "1" },
   success: function (data) {
    alert(data)
   },
   error: function () {
    alert("error")
   }
  });
 })
})

也是500的状态码。

以上内容就是本文的全部叙述,切记ajax中要带上antiforgerytoken防止csrf攻击,小伙伴们在使用过程发现有疑问,请给我留言,谢谢!