加入收藏 | 设为首页 | 会员中心 | 我要投稿 河北网 (https://www.hebeiwang.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 建站 > 正文

任意URL跳转漏洞修复与JDK中getHost()方法之间的坑

发布时间:2019-03-17 12:38:42 所属栏目:建站 来源:ChangeS
导读:恣意URL跳转裂痕 处事端未对传入的跳转url变量举办搜查和节制,导致可恶意结构恣意一个恶意地点,诱导用户跳转到恶意网站。因为是从可信的站点跳转出去的,用户会较量信赖,以是跳转裂痕一样平常用于垂纶进攻,通过转到恶意网站诱骗用户输入用户名和暗码偷取用
副问题[/!--empirenews.page--]

恣意URL跳转裂痕

处事端未对传入的跳转url变量举办搜查和节制,导致可恶意结构恣意一个恶意地点,诱导用户跳转到恶意网站。因为是从可信的站点跳转出去的,用户会较量信赖,以是跳转裂痕一样平常用于垂纶进攻,通过转到恶意网站诱骗用户输入用户名和暗码偷取用户信息,或诱骗用户举办款子买卖营业。

修复该裂痕最有用的要领之一就是校验传入的跳转url参数值,判定是否为预期域名。在java中可行使下列要领:

  1. String url = request.getParameter("returnUrl"); 
  2. String host = ""; 
  3. try { 
  4.     host = new URL(url).getHost(); 
  5. } catch (MalformedURLException e) { 
  6.     e.printStackTrace(); 
  7. if host.endsWith(".bbb.com"){ 
  8.     //跳转 
  9. }else{ 
  10.     //不跳转,报错 

上述代码中首要校验了客户端传来的returnUrl参数值,行使java.net.URL包中的getHost()要领获取了将要跳转url的host,判定host是否为方针域,上述代码中限定了必需跳转到xxx.bbb.com的域名,从而解除了跳转到不行信域名的也许。

可是,getHost()要领真的靠谱吗??

getHost()要领的坑之一

可以被反斜线绕过,即returnUrl=http://www.aaa.comwww.bbb.com会被代码以为是将要跳转到bbb.com,而现着实赏识器中反斜线被更正为正斜线,跳转到www.aaa.com/www.bbb.com,最终照旧跳到www.aaa.com的处事器。

行使下列代码举办测试:

  1. public class Main { 
  2.  
  3.     public static void main(String[] args) { 
  4.         String url = "https://www.aaa.comwww.bbb.com?x=123"; 
  5.         String host = ""; 
  6.         try { 
  7.             host = new URL(url).getHost(); 
  8.         } catch (MalformedURLException e) { 
  9.             e.printStackTrace(); 
  10.         } 
  11.         System.out.println("host---"+host); 
  12.         System.out.println("url---"+url); 
  13.     } 

url参数的域名getHost()之后是www.aaa.com照旧www.bbb.com呢?打印功效如下:

恣意URL跳转裂痕修复与JDK中getHost()要领之间的坑

该功效会被endsWith(“.bbb.com”)要领判定为真,从而乐成执行跳转,但现着实赏识器中跳转到了www.aaa.com网站。

getHost()要领的坑之二

getHost()要领的功效在差异JDK版本中对井号#的处理赏罚功效差异,凡是井号被用作页面锚点,对付https://www.aaa.com#www.bbb.com?x=123这个url,较高版本的JDK中,取出功效为www.aaa.com,低版本中为www.aaa.com#www.bbb.com,从而低版本又可绕过endsWith(“.bbb.com”)要领,乐成跳转。

这里所说的高版本指的是java version 1.8.0_181可能java version 1.7.0_161中的181和161,与JDK7照旧8无关。也许java在某个时刻齐集修复了JDK6/7/8中的URL库。

测试进程中发明1.6.0_45,1.7.0_71,1.8.0_25均可被#绕过,即差异的JDK中低版本均存在题目。

通过比拟rt.jar---java---net--URLStreamHandler.java代码(低版本为左边,高版本为右边)找到题目地址如下图所示,代码中的start为url中冒号位置,limit为url中井号位置:

从代码中可以发明,低版本中未思量到一个完备url中斜线/可能问号?之前会呈现井号#的环境,假如url中有斜线/可能问号?,取host就以斜线可能问号为终止,纵然中间包括井号也不处理赏罚;而高版本中举办了井号位置的判定,解除了行使井号绕过的也许。可是线上天生情形的JDK版本又不是敢任意乱进级的,只能从代码里提前提防。

下图为行使差异版本JDK测试的功效:

统一段代码在差异JDK版本中打印出的host值差异,在低版本中包括了井号及厥后边的部门。

综合上述两个坑,若想行使getHost()来修复恣意URL跳转裂痕,必要思量到反斜线和井号绕过,,可行使如下代码:

  1. String url = request.getParameter("returnUrl"); 
  2. String host = ""; 
  3. try { 
  4.     urlurl = url.replaceAll("[\#],"/"); //替代掉反斜线和井号 
  5.     host = new URL(url).getHost();   
  6. } catch (MalformedURLException e) { 
  7.     e.printStackTrace(); 
  8. if host.endsWith(".bbb.com"){ 
  9.     //跳转 
  10. }else{ 
  11.     //不跳转,报错 

附送一个真实例子

(编辑:河北网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读