前端也须要了解的 JSONP 安全

什么是 JSONP(JSON with Padding)?

What? 你还不知道 JSONP 是什么?赶忙去补补吧,我就很少讲了。 补个百度百科连接先,baike.baidu.com/item/jsonp/…javascript

会有哪些安全隐患?怎么防范?

咱们假设有这样一个场景一
我登陆了 www.qq.com,QQ 为了给第三方提供服务,可能会有这样的 jsonp 接口,www.qq.com/getUserInfo?callback=action,那我就能够本身构造一个恶意页面,请求这个 jsonp 接口,放在网络上,收集 qq 用户的信息了。要是 jsonp 接口还涉及了一些敏感操做或者信息,就更嗨皮了~好比登录啊,删除啊等操做。不过国内不少后端开发并不重视此问题,忽然想起来老东家的后端开发为了加速开发,写了个通用的函数,只要能 GET 访问的接口均可以 jsonp 访问。Emmm...html

对于第一种状况,首先要验证 JSONP 调用的来源(Referer),这种方案利用了 js 资源加载时会发送 Referer 的特性,服务端判断 Referer 是否是白名单便可。
提及来容易,但实际还会由于过滤的正则不严谨致使绕过,好比只验证了是否存在 www.qq.com 关键字,那我能够构造 www.qq.com.domain.com 来进行攻击。又好比不少开发会容许空 Referer,而跨协议调用 js 是不发送 Referer 的,可谓是千里之堤溃于蚁穴~跨协议调用 js 的一个例子: <iframe src="javascript:'<script src=http://attack.com/jsonp></script>'"></iframe> 代码里使用 iframe 调用 javascript 伪协议,来发送空 Referer 的 js 请求。
因此空 Referer 仍是要禁止滴。
另外就是部署随机 Token 来防护了,每一次请求都带上 token 值,token 值字母加数字长一点最好了,否则有被暴力破解的可能。前端

接下来是场景二
不严谨的 content-type 致使的 XSS 漏洞 想象一下 jsonp 就是你请求 http://youdomain.com?callback=douniwan, 而后返回 douniwan({ data }),那假如请求 http://youdomain.com?callback=<script>alert(1)</script> 不就返回 <script>alert(1)</script>({ data }) 了吗,若是没有严格定义好 Content-Type( Content-Type: application/json ),再加上没有过滤 callback 参数,直接当 html 解析了,就是一个赤裸裸的 XSS 了。 Content-Type 设置成 application/javascript 在 IE 等浏览器下同样能够解析成 HTML 致使 XSS 漏洞。因此要严格定义成 application/json。不过即便这样,在五花八门的浏览器面前,也会有个别特殊的,好比在 IE6/7 下面,请求的 URL 文件后面加一个 /x.html 就能够解析成 html。java

防护这种状况首先要严格定义 Content-Type: application/json,而后严格过滤 callback 后的参数而且限制长度。
有时候咱们会在某些框架的内置 jsonp 函数返回内容里看到这样的开头:/**/, 好比 Express 框架内置的 jsonp 函数会这样返回:git

/**/ typeof func === 'function' && func({"data":"hello"});
复制代码

这是为何呢?其实这都是有历史缘由的,2011 年的时候出过一个经过 mhtml 协议解析跨域的漏洞:MHTML Mime-Formatted Request Vulnerability (CVE-2011-0096),当时也是影响了一堆国际厂商,想详细了解的能够戳这里,technet.microsoft.com/library/sec…
防护这个就是在前面加上 /**/ 或者多个换行符就能必定程度预防其余文件格式的输出了。github

接下来是场景三
假如个人网站用了第三方的服务,而对方提供的只有 jsonp 接口,万一对方的服务器被黑了,返回了一串恶意代码,那不是城门失火,殃及池鱼了吗?
请记住一句话,全部的第三方都是不可彻底信任的。
防护的话,首先,考虑一下,前端能作什么防护措施?
iframe?好像能够,搜了下,网上已经有人作了尝试了,详细能够看这里 github.com/aui/jsonp-s…
还有什么方法呢?前端好像没什么能够检测返回的 js 内容的函数了,好像没什么能够玩的了。
那换个思路,服务端转发呢,既然前端不能检测第三方的 jsonp 内容,那我用本身的服务端去检测第三方的 jsonp 内容是否合法,再返回结果不就好了。json

最后

绕来绕去,总感受用的不太爽,可能正是因为 jsonp 的种种缺陷,才一直没有被浏览器标准采纳吧。后端

相关文章
相关标签/搜索