• 一个若白,若白博客,欢迎您的访问,若白博客将全速为您展示全网优秀文章。

  • 男人最无奈的大概就是在最无力的年纪遇见最想照顾一辈子的人

  • :evil:这一回可是真的要做好一个博客咯

    加油!

保护 Go 跳转,防止被恶意利用

体会 一个若白 6个月前 (07-27) 100次浏览 0个评论 扫描二维码
文章目录[隐藏]

或者是出于优化 SEO,或者是出于增强网站体验,患上多博客都给文章中的外部链接加之了个二次跳转,本博客也不破例。

比如说我在这插入一个 baidu 的超链接,你点击访问后先会被跳转到本博客的跳转页面,一段动画后才会真的转至 baidu 的首页。

看似入情入理,实则隐蔽一个小破绽!

情境剖析

举个栗子,倘若有个不怀好心的坏蛋,要流传一个不怀好心的网站 http://www.baidu.com (这里用 baidu 做树模好了。。),一般这种网站一发到 QQ 里 QQ 就会有一个年夜年夜的血色叹号以示危险:
保护 Go 跳转,防止被恶意利用

如果应用像本站的跳转性能,就能够不便地将链接“洗白”:

保护 Go 跳转,防止被恶意利用

如果有不明真相的小白点击了,在本站的“跳转”下终究访问的就会是恶意的链接网址,无辜的链接跳转性能瞬间成为了“走狗”。

解决设施

那末怎样防范这种状况的发生呢?

我的思路是如许的:

在跳转页面中,先用 PHP 的‘$_SERVER[“HTTP_REFERER”]’函数获取泉源链接,而后坚定泉源链接是否属于本站,如果否,再坚定跳转链接,如果跳转链接也不属于本站,就给出一个提醒:你将要访问的网站不属于本站范围,请警惕访问。反之则失常跳转。
保护 Go 跳转,防止被恶意利用

这里有个难点便是坚定宗旨网址是否属于本站的一个页面,也便是对于“敌我”的一个坚定。

比方说本站的网址是 http://mkblog.cn ,一些二级页面如 http://zb.mkblog.cn、https://mkblog.cn/about 也属于本站。而 http://www.baidu.com/?mkblog.cn 尽管蕴含“mkblog.cn”,访问后它却是 baidu 的首页。因而不能轻易平以及的通过坚定网址中是否存在 “mkblog.cn” 来患上出论断

仔细的考察域名的构造你就会发明只有是属于 mkblog.cn 的网址一定会满足下列法则:

  • 如果 mkblog.cn 的前面有内容,那末一定不会有“?”浮现,比如说 abc?.mkblog.cn 是不存在的
  • 如果 mkblog.cn 的前面还跟有内容,那末一定是“/”,或者“?”,比如说 mkblog.cn/123 或者 mkblog.cn?from=123

应用以上两个法则写了个坚定函数下列:

  1. /**
  2.  * 坚定是否自身的域名
  3.  * @param $domain 要停止坚定的域名
  4.  * @param $my 自身的域名
  5.  * @return 比照效果
  6.  */
  7. function isMyDomain($domain$my) {
  8.     preg_match(‘/([^?]*)/i’, $domain$match);
  9.     if(isset($match[1])) $domain = $match[1];
  10.     preg_match(‘/([w-]*.[w-]*)/.*/i’, $domain.’/’, $match);
  11.     if(isset($match[1]) && $match[1] == $myreturn true;
  12.     return false;
  13. }

终究代码

遵循以上思路完玉成部跳转页面的编写后,测试了一下效果非常不错:只有是从本站点开的跳转网址,都能失常停止跳转,从而第三方关上的跳转,则会弹出提醒。

终究完好的跳转页面源代码下列:(代码中的坚定思路一定不惟一,如果您有更好的坚定形式,驱逐在下方留言交换!)

2017/3/3 版存在一些 BUG,仅供参考,已经被折叠。新版请返回文末

效果演示

照样以 baidu 为例,如果你 点击 https://mkblog.cn/go/?url=www.baidu.com 访问,间接就跳转了,如果你手动复制这个跳转网址再粘贴到浏览器访问,则会弹出提醒。

如果是本站的站内链接,如 https://mkblog.cn/go/?url=zb.mkblog.cn 不管以何种形式关上都是间接跳转。

2017-3-13 更新

通过谈论区的列位展现(感谢 @懿古今 @Tokin @a 指出问题),发明以前的版本存在 在微信中无奈跳转、在整体浏览器中无奈敞开页面、开启了 https 的站点无奈获取 HTTP_REFERER 等状况。

现修复了这些问题的一整体。整体浏览器因为自身就屏障了敞开页面的 js 函数,以是照样会照成无奈敞开页面的状况。(尽力了…)

至于 https 无奈获取 HTTP_REFERER 的状况,现在我的站点都不加 https ,欠好测试,baidu 了一下也找不到好的解决心划,临时尚无解决心划……

更新后的代码下列

  1. <?php
  2. /**
  3.  * 带有去路考证以及跳转提醒性能的跳转页面
  4.  * @auth 孟坤博客
  5.  * @authUrl http://mkblog.cn
  6.  * @data 2017/3/13
  7.  * @url https://mkblog.cn/701
  8.  */
  9. // 请将这里的网址改为自身的(顶级)域名所在
  10. $myDomain = ‘mkblog.cn’;
  11. // 这里用正则提取 $_SERVER[“QUERY_STRING”] 而不是间接 get url
  12. // 是因为如果链接中自身带有 GET 参数则会以致获取不完好
  13. preg_match(‘/url=(.*)/i’, $_SERVER[“QUERY_STRING”], $jumpUrl);
  14. // 如果没获取到跳转链接,间接跳回首页
  15. if(!isset($jumpUrl[1])) {
  16.     header(“location:/”);
  17.     exit();
  18. }
  19. $jumpUrl = $jumpUrl[1];
  20. // 坚定是否蕴含 http:// 头,如果不则加之
  21. preg_match(‘/(http|https):///’, $jumpUrl, $matches);    
  22. $url = $matches$jumpUrl: ‘http://’. $jumpUrl;
  23. // 坚定网址是否完好
  24. preg_match(‘/[w-]*.[w-]*/i’, $url$matche);
  25. // 是否需要给出跳转提醒
  26. $echoTips = false;
  27. if($matche){
  28.     // 如果是本站的链接,不展现动画间接跳转
  29.     if(isMyDomain($url$myDomain)) {
  30.         header(“location:{$url}”);
  31.         exit();    // 后续操纵再也不实行
  32.     }
  33.     $title = ‘页面加载中,请稍候…’;
  34.     $fromUrl = isset($_SERVER[“HTTP_REFERER”])? $_SERVER[“HTTP_REFERER”]: // 获取泉源 url
  35.     // 如果泉源以及跳转后的所在都不是本站,那末就要给出提醒
  36.     if(!isMyDomain($fromUrl$myDomain)) {
  37.         $echoTips = true;
  38.     }
  39. else {    // 网址参数不完好
  40.     $url = ‘/’;
  41.     $title = ‘参数同伴,正在返回首页…’;
  42. }
  43. /**
  44.  * 坚定是否自身的域名
  45.  * @param $domain 要停止坚定的域名
  46.  * @param $my 自身的域名
  47.  * @return 比照效果
  48.  */
  49. function isMyDomain($domain$my) {
  50.     preg_match(‘/([^?]*)/i’, $domain$match);
  51.     if(isset($match[1])) $domain = $match[1];
  52.     preg_match(‘/([w-]*.[w-]*)/.*/i’, $domain.’/’, $match);
  53.     if(isset($match[1]) && $match[1] == $myreturn true;
  54.     return false;
  55. }
  56. ?>
  57. <html>
  58. <head>
  59. <meta http-equiv=“Content-Type” content=“text/html; charset=UTF-8”>
  60. <meta http-equiv=“X-UA-Compatible” content=“IE=edge”>
  61. <meta name=“viewport” content=“width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no”>
  62. <?php
  63. if($echoTips) {
  64.     echo ‘<title>跳转提醒</title>’;
  65. else {
  66.     echo ‘<meta http-equiv=“refresh” content=“0;url=’.$url.'”>’;
  67.     echo ‘<title>’.$title.'</title>’;
  68. }
  69. ?>
  70. <style>
  71. body{background:#fff;font-family:Microsoft Yahei;-webkit-animation:fadeIn 1s linear;animation:fadeIn 1s linear}
  72. @-webkit-keyframes fadeIn{from{opacity:0}
  73. to{opacity:1}
  74. }@keyframes fadeIn{from{opacity:0}
  75. to{opacity:1}
  76. }#circle{background-color:rgba(0,0,0,0);border:5px solid rgba(0,183,229,0.9);opacity:.9;border-right:5px solid rgba(0,0,0,0);border-left:5px solid rgba(0,0,0,0);border-radius:50px;box-shadow:0 0 35px #2187e7;width:50px;height:50px;margin:0 auto;position:fixed;left:30px;bottom:30px;-moz-animation:spinPulse 1s infinite ease-in-out;-webkit-animation:spinPulse 1s infinite ease-in-out;-o-animation:spinPulse 1s infinite ease-in-out;-ms-animation:spinPulse 1s infinite ease-in-out}
  77. #circle1{background-color:rgba(0,0,0,0);border:5px solid rgba(0,183,229,0.9);opacity:.9;border-left:5px solid rgba(0,0,0,0);border-right:5px solid rgba(0,0,0,0);border-radius:50px;box-shadow:0 0 15px #2187e7;width:30px;height:30px;margin:0 auto;position:fixed;left:40px;bottom:40px;-moz-animation:spinoffPulse 1s infinite linear;-webkit-animation:spinoffPulse 1s infinite linear;-o-animation:spinoffPulse 1s infinite linear;-ms-animation:spinoffPulse 1s infinite linear}
  78. @-webkit-keyframes spinPulse{0%{-webkit-transform:rotate(160deg);opacity:0;box-shadow:0 0 1px #505050}
  79. 50%{-webkit-transform:rotate(145deg);opacity:1}
  80. 100%{-webkit-transform:rotate(-320deg);opacity:0}
  81. }@-webkit-keyframes spinoffPulse{0%{-webkit-transform:rotate(0deg)}
  82. 100%{-webkit-transform:rotate(360deg)}
  83. }#loading-text{position:fixed;left:110px;bottom:35px;color:#736D6D}
  84. @media screen and (max-width:600px){#circle,#circle1{left:0;right:0;top:0;bottom:0}
  85. #circle{margin:120px auto}
  86. #circle1{margin:130px auto}
  87. #loading-text{display:block;text-align:center;margin-top:220px;position:static;margin-left:10px}
  88. }
  89. .warning{max-width: 500px;margin: 20px auto;}
  90. .wtitle {font-size: 22px;color: #d68300;}
  91. .wurl {overflow: hidden;text-overflow: ellipsis;white-space: nowrap;color: #827777;}
  92. .btn {display: inline-block;line-height: 20px;cursor: pointer;border: 1px solid #A9A6A6;padding: 6px 10px;font-size: 14px;text-decoration: none;}
  93. .btn-green {color: #fff;background-color: #238aca;border: 1px solid #238aca;}
  94. .btn:hover {background-color: #A9A6A6;border: 1px solid #A9A6A6;color: #fff;}
  95. </style>
  96. </head>
  97. <body>
  98.     <?php if($echoTips) { ?>
  99.     <div class=“warning”>
  100.         <p class=“wtitle”>您将要访问:</p>
  101.         <p class=“wurl” title=“<?php echo $url;?>”><?php echo $url;?></p>
  102.         <p>该网站不属于孟坤博客,咱们无奈确认该网页是否平安,它能够蕴含未知的平安隐患。</p>
  103.         <a class=“btn btn-green” href=“<?php echo $url;?>” rel=“nofollow”>连续访问</a>
  104.         <span class=“btn” onclick=“closePage()”>敞开网页</span>
  105.     </div>
  106.     <script>
  107.     function closePage() {
  108.         // 通用窗口敞开
  109.         window.opener=null;
  110.         window.open(,’_self’);
  111.         window.close();
  112.         // 微信浏览器敞开
  113.         WeixinJSBridge.call(‘closeWindow’);
  114.     }
  115.     </script>
  116.     <?php } else { ?>
  117.     <div id=“circle”></div>
  118.     <div id=“circle1”></div>
  119.     <p id=“loading-text”>页面加载中,请稍候…</p>
  120.     <?php } ?>
  121. </body>
  122. </html>

若白博客 , 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:保护 Go 跳转,防止被恶意利用
喜欢 (1)
关于作者:
个人博客,高中生。
发表我的评论
取消评论
表情 贴图 加粗 删除线 居中 斜体 签到