>[info]Json劫持漏洞
Json劫持漏洞主要是针对接口返回JSONP或JSON这类数据处理不够存在的安全隐患。
当前政务内网安全评测监测JSON劫持主要是通过canllback handle传入特殊构造的非法字符,例如传入callback=jsonp9527,如果在返回的结果中匹配到特征码^jsonp9527999\(|^\[.*(\];|\])$|^.{1,50}\([\[\{]+".*[\]\}]+\);$则认为存在JSON劫持。当前规则下无法完全根除检测报告中出现JSON劫持特征码,但是建议从下面几个方面入手:
(1)、强化JSONP输出的handle部分的验证处理
需要修改\thinkphp\library\think\response\Hsonp.php 24行 output函数
~~~
protected function output($data)
{
try {
// 返回JSON数据格式到客户端 包含状态信息 [当url_common_param为false时是无法获取到$_GET的数据的,故使用Request来获取<xiaobo.sun@qq.com>]
$Request =Request::instance();
$var_jsonp_handler = $Request->param($this->options['var_jsonp_handler'], "");
$handler = !empty($var_jsonp_handler) ? $var_jsonp_handler : $this->options['default_jsonp_handler'];
//访问来路验证
$reffer =$Request->server('HTTP_REFERER');
if(!$reffer){//访问来路为空(直接输入URL访问则不输出JSPNP数据)
return '非法请求方式';
}else{
$parseInfo =parse_url($reffer);
$host =strtolower($parseInfo['host']);
$domains =parse_url($Request->domain());
if(strtolower($domains['host'])!=strtolower($parseInfo['host'])){
return '非法请求方式!';
}
}
//为了应对安全评测强加的callback handle 规则
if(!preg_match('/^([a-z]+)$/iS',$handler)){
//$handler =$this->options['default_jsonp_handler'];
return '非法的jsonp handle'; //不符合规则时不返回jsonp数据
}
$data = json_encode($data, $this->options['json_encode_param']);
if ($data === false) {
throw new \InvalidArgumentException(json_last_error_msg());
}
$data =escapeshellcmd($handler) . '(' . $data . ');';
return $data;
} catch (\Exception $e) {
if ($e->getPrevious()) {
throw $e->getPrevious();
}
throw $e;
}
}
~~~
此段代码主要是验证了访问来路验证和输出的callback handle处理。
(2)、在入口文件中增加防止跨域访问的验证处理
~~~
$origins =['yuanan2.demo.neikongcn.com','localhost','api.n3.cn','10.27.29.1','jgfw.yichang.gov.cn'];
$allowOrigin ='localhost';
if(isset($_SERVER['HTTP_ORIGIN']) && in_array($_SERVER['HTTP_ORIGIN'],$origins)){
$allowOrigin =$_SERVER['HTTP_ORIGIN'];
}
header("Access-Control-Allow-Origin: ".$allowOrigin);
~~~
[注意]:hader的设置必须在有任何输出之前完成。
(3)、尽量要求所有需要返回JSON或者JSONP的接口或控制器先验证登录权限后再有数据输出。