JSONP安全防范解决方案新思路

jsonp安全性防范,分为如下几点: javascript

一、防止callback参数意外截断js代码,特殊字符单引号双引号,换行符均存在风险
    二、防止callback参数恶意添加标签(如script),形成XSS漏洞
    三、防止跨域请求滥用,阻止非法站点恶意调用 php

针对第三点,咱们能够经过来源refer白名单匹配,以及cookieToken机制来限制
    而前两点,传统的作法分为如下几种:
    一、纯手工过滤特殊字符,引号尖括号等,一旦发现潜在恶意字符则服务端拒绝,返回错误。此种方式较为严格,可是随之而来的问题是失败率会有所提高,尤为对于对外开发者。并且JS中恶意字符的变形十分多,此方式须要枚举全部非法字符,可能存在疏漏。咱们不该该将潜在的恶意字符都一律屏蔽,由于确实有些需求须要传入并存储这些字符。
    二、对于callback参数做严整的格式检查,或强制约定指定格式。基本能够完全解决安全问题,但一样是对调用端不是彻底透明,使用者须要额外去知晓相关限制和约定,可能会形成没必要要的沟通成本。
    三、返回包体添加header头部,强制指定MIME类型,避免按HTML方式解析,防止XSS漏洞。这彷佛是个很完美的解决方案。可是十分诡异的是,在某些版本的火狐浏览器下,直接访问MIME类型为JAVASCRIPT的请求时,浏览器仍然会按照HTML解析。或许是该浏览器设计的缺陷,但它忽略了咱们设置的header。没法保证全部浏览器严格按照MIME类型解析。 java

咱们的关注点一直在于如何限制用户输入,可是请从另一个层面去考虑该问题,或许就会豁然开朗。 chrome

咱们先了解一下JS自己的特性。
    JSONP的本质是构造全局回调函数,以后加载script标签触发回调函数。
    一般咱们使用函数能够这么写 json

function test(){}test();

而在全局的函数也就默认是window的成员。也能够显示书写为 跨域

window.test = function(){};window.test();

而JS中对象的成员是可使用字符串索引的方式访问的,故进一步改造为 浏览器

window['test']=function(){};window['test']();

如今有注意到么,如此一来咱们已经把函数名已经彻底限制在了字符串上下文,理论上只要作好了防注入工做,callback参数是不可能跳出字符串上下文意外执行代码的。以PHP为例,单字符串防止注入甚至能够直接使用json_encode该字符串实现。 安全

window['alert("123");abc']();

上面的callback参数虽然有注入的风险,能够因为callback参数严格限制在字符串内部,仅会做为文本,不会意外执行 cookie

但仍然存在xss漏洞问题,看下面例子 xss

window['<script>alert(123);</script>']();

咱们虽然已经保证了<script>严格限制在引号内部,不会形成js注入,可是直接在浏览器中输入该jsonp请求仍会按照HTML解析,产生XSS漏洞,即使设置了header也很难防范。

在进一步,咱们只须要保证浏览器内不会明文出现<>标签,那么问题即可完全解决。
基本思路是在服务端作一次urlencode。而在output输出decodeURIComponent(‘#####’)来规避显示尖括号。Urlencode过的字符串,只可能包含字母数字%,也顺便解决了注入的问题

最终附上一段简短的代码。根本解决jsonp的安全问题

<?php header('Content-type: text/javascript'); //加上此句能够消除chrome的警告 
    $callback = urlencode($_GET['callback']); 
    echo "window[decodeURIComponent('{$callback}')]
    ({ret:0,msg:’OK’});"

请求1:http://www.test.com/a.php?callback=alert(123);abc

响应1:window[decodeURIComponent('alert(123)%3Babc')]({ret:0,msg:'OK'});

请求2:http://www.test.com/a.php?callback=<script>alert(123);</script>

响应2:window[decodeURIComponent('%3Cscript%3Ealert(123)%3B%3C%2Fscript%3E')]({ret:0,msg:'OK'});

上述几个例子均可以证实jsonp安全漏洞已被完全规避,即使存在尝试注入的恶意参数,仍能最大限度保证程序彻底正常工做触发回调。

相关文章
相关标签/搜索