首先必须明白 jsonp 是一个什么场景使用:
有种跨域获取数据的方法jsonp: js 标签 script 可以实现src中的地址不受同源策略限制进行数据访问及获取;
JSONP的原理:(JSONP请求一定需要对方的服务器做支持才可以)
在script的世界中,没有同源跨域这一说,只要你给我src属性中的地址是一个合法的地址,script标签就可以把对应的内容请求回来。
JSONP就是利用了SCRIPT的这个原理
1)、我们把需要请求数据的那个跨域的API数据接口的地址赋值给SCRIPT的SRC
2)、把当前页面中的某一个函数名当做参数值传递给需要跨域请求数据的服务器(URL问号传参:?callback=fn)
3)、服务器接收到你的请求后,需要进行特殊的处理:把你传递进来的函数名和它需要给你的数据拼接成一个字符串 例如我们传递进去的函数名是fn,它准备好的数据是'fn([{"name":"zhangsan"}])' ->我们传递的函数名(需要给我们的数据)
4)、最后服务器把准备的数据通过协议返回给我们客户端,客户端发现其实就是让我们的fn执行,而且还给fn传递了一堆的数据,那些数据就是我们想要的
代码如下:
<script>
function fn(data){
console.log(data);//这里面就是服务器传递给我们的数据
}
</script>
<script charset='utf-8' type='text/javascript' src='http://matchweb.sports.qq.com/kbs/calendar?columnId=100000&callback=fn'></script>
模拟后台jsonp处理代码
if(pathname==="/getAll"){
//接收客户端传递进来的函数名
var fnName = query["callback"];
//准备数据
var con = fs.readFileSync('./custom.json','utf-8');
//返回给客户端内容
res.writeHead(200,{'content-type':'text/javascript;charset=utf-8'});
res.end(fnName+"("+con+")");
}
在JSONP中服务器端返回给客户端的数据一般都是JSON格式的字符串
以上我们明白了背景及jsonp的使用,
后面来分析一下这里存在的安全风险:
如果B是正常网站,为用户提供服务,有个服务接口使用了jsonp的方式提供服务,可查询用户信息,如
可供C、D等非同源网站进行访问;(当然是需要进行cookie、令牌等身份凭证进行鉴权)
那攻击者构建一个恶意链接或恶意网站A,采用jsonp方式请求,来获取用户信息,并执行其它操作,如传递到攻击者的服务器,这样攻击者就收到了受害者的信息;
危害:
取决于采用jsonp提供服务的接口所提供的功能,(一般都是获取数据,那就看数据的敏感成度
防御:
有没有觉得这个方式跟csrf的利用方式有点像,都是构造恶意链接/网站 诱导攻击者来访问,从而利用网站/服务自身的实现方式(正常功能)来执行攻击者想要的操作或数据获取;
从这个角度来说 都是钻了实现方式的空子,这点上是共同的:csrf是可伪造请求,jsonp劫持也是可伪造请求;
不同的是:csrf是通过抓包观察正常请求参数来伪造恶意请求(利用了客户端存储的身份凭证,只是执行功能操作,无数据返回需求),jsopn是本身就支持跨域,恶意请求随意写,被恶意使用(获取数据并将数据按恶意请求中的js做功能外操作);这样看也谈不上伪造?只能说是欺骗?
说回防御:jsonp应在使用时,增加一个正常双方知晓的凭证,可以是一次性token,可以是域名白名单,可以是验证refer(也是白名单);
题外话:从利用原理及防御手段的一次性token来说,有人把jsonp说成是一种csrf也是情理之中?~!