zoukankan      html  css  js  c++  java
  • URL重定向及跳转漏洞

    URL跳转漏洞

       URL 跳转漏洞是指后台服务器在告知浏览器跳转时,未对客户端传入的重定向地址进行合法性校验,导致用户浏览器跳转到钓鱼页面的一种漏洞。

    使用场景

       现在 Web 登录很多都接入了QQ、微信、新浪等第三方登录,以 QQ 第三方授权登录为例说明,在我们调用 QQ 授权服务器进行授权时,会在参

    数中传入redirect_url(重定向)地址,告知 QQ 授权服务器,授权成功之后页面跳转到这个地址,然后进行站点登录操作。但是如果你的重定向地址在

    传输过程中被篡改成了一个钓鱼网址,那么就是导致用户的授权信息被非法获取。当然,QQ 第三方登录,也会有自己的策略,就是接入 QQ 第三方

    登录的应用,会在开发者平台,配置相关的跳转白名单,只有属于白名单中的域名、子域名或 url ,QQ授权服务器才跳转,如果发现 redirect_url 不

    合法,则跳转到非法页面。

    防御策略

       根据上面的场景分析,我们知道,之所以会出现跳转 URL 漏洞,就是因为服务端没有对客户端传递的跳转地址进行合法性校验,所以,预防这种攻

    击的方式,就是对客户端传递过来的跳转 URL 进行校验。

    常用的方式:

    服务端配置跳转白名单或域名白名单,只对合法的 URL 做跳转

    下面是关于PHP服务端对客户端传递过来的跳转 URL 进行校验的代码:

    <?php
    
    // $allowedDomains 表示允许跳转的url白名单
    $allowedDomains = array(
    		"aaaa.com"
    		"bbbb.com"
    		.......	
    	);
    function encodeUrl($urlInfo)
        {/*{{{*/
            $path = isset($urlInfo['path']) ? $urlInfo['path'] : '';
            if(!empty($path))
            {
            	$t = explode("/", $path);
            	
            	for($i = 0; $i < count($t); $i++)
            	{
            		$t[$i] = rawurlencode($t[$i]);        		
            	}
            	$path = implode("/", $t);
            }
        	$query = isset($urlInfo['query']) ? $urlInfo['query'] : '';
            if(!empty($query))
            {
            	$t = explode("&", $query);
            	
            	for($i = 0; $i < count($t); $i++)
            	{
            		$tt = explode("=", $t[$i]);
            		$tt[1] = rawurlencode($tt[1]);
            		$t[$i] = implode("=", $tt);        		
            	}
            	$query = implode("&", $t);
            }
            if(!isset($urlInfo['host']) || empty($urlInfo['host']))
            {
            	return $path. "?". $query;
            }
            $scheme = isset($urlInfo['scheme']) ? $urlInfo['scheme'] : 'http';
            $port = isset($urlInfo['port']) ? $urlInfo['port'] : 80;
    
            
            $request = $scheme . '://'. $urlInfo['host'];
            $request .= ($port == 80) ? '' : ':'.$port;
            $request .= $path;
            $request .= (empty($query)) ? '' : '?'.$query;
            return $request;
        }/*}}}*/
    	
    function checkUrl($url,$domainArr=array())
    	{/*{{{*/
    		$res = array('isTrustedDomain' => false,'url' => '','domain' => '');
    		if(empty($url))		return $res;
    		$domainArr = empty($domainArr) || !is_array($domainArr) ? $allowedDomains : $domainArr;
    		$url	  = filterUrl($url);//先过滤特殊字符
    		$p      = parse_url($url);
    		$scheme = $p['scheme'];
    		if(!in_array(strtolower($scheme),array('http','https'))){
    			return $res;
    		}
    		
    		$host   = $p['host'];
    		if(!isValidHost($host)){
    			return $res;
    		}
    		$hostLen = strlen($host);
    		foreach($domainArr as $domain){
    			$firstPos = strpos($host, $domain);
    			if($firstPos !== false && ($firstPos + strlen($domain)) == $hostLen){
    				
    				if($firstPos == 0 || $domain[0] == '.' || $host[$firstPos-1] == '.'){
    					$res['isTrustedDomain'] = true;
    					$res['url'] 		  				= $url;
    					$res['domain'] 				= $domain;
    					break;
    				}
    			}
    		}
    		return $res;
    	}/*}}}*/
    
    function filterUrl( $url )
    	{/*{{{*/
    		if(empty($url)) return $url;
    		// Strip all of the Javascript in script tags out...
    		$url = preg_replace('/<SCRIPT.*?</SCRIPT>/ims',"",$url);
    		// Strip all blank character
    		$url = preg_replace('/[sv]+/',"",$url);
    		//Strip special characters(',",<,>,)
    		$url = str_replace(array("'",""","<",">","\"),'',$url);
    		return $url;
    	}/*}}}*/
    
    function isValidHost($host)
    	{/*{{{*/
    		$p = "/^[0-9a-zA-Z-.]+$/";
    		return preg_match($p,$host) ? true : false;
    	}/*}}}*/
    	
    $url = "https://www.baidu.com";
    $call_back_url = trim($url);
    $call_back_url = encodeUrl(parse_url(urldecode($call_back_url)));
    $res = checkUrl($call_back_url, $domainArr);
    
    var_dump($res);
    

      

  • 相关阅读:
    vue简单分屏(1,4,9,16),全屏,还需要调整
    vue 中的Vuex实践
    常用工具类
    java Log日志规范
    spring中对象的注入方式
    不恰当的update语句使用主键和索引导致mysql死锁
    JPA规范及其它持久层框架
    webservice基本功能介绍
    Activiti工作流(二)之常用操作
    Activiti工作流(一)之基本操作介绍
  • 原文地址:https://www.cnblogs.com/leeyongbard/p/9958302.html
Copyright © 2011-2022 走看看