关闭恼人的微信网址拦截

· 3 min read

在微信中打开一些网页时总会出现以下拦截提醒,遇到这种情况时必须点击继续访问。技术人不忍这种流氓事,于是着手从技术上解决这个体验问题。

Tampermonkey浏览器插件

首先想到的是这个方案,解决步骤如下

  1. Chrome浏览器下安装插件Tampermonkey(油猴)

  2. 插件中增加如下脚本,该脚本我已已经开源,不想了解具体实现的直接安装即可。

    // ==UserScript==
    // @name         Redirect URL
    // @namespace    https://1991421.cn
    // @version      0.1
    // @description  解决恼人的网页拦截,比如微信打开链接
    // @author       Alan He
    // @match        https://weixin110.qq.com/cgi-bin/mmspamsupport-bin/newredirectconfirmcgi*
    // @icon         data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==
    // @grant        none
    // @run-at document-end
    // ==/UserScript==
    
    (function() {
        'use strict';
         function htmlDecode(input) {
            var doc = new DOMParser().parseFromString(input, 'text/html');
            return doc.documentElement.textContent;
          }
    
        if(window.location.href.match(/^https:\/\/weixin110.qq.com\/cgi-bin\/mmspamsupport-bin\/newredirectconfirmcgi/)){
          window.location.href=htmlDecode(cgiData.url);
        }
    })();
    

如上操作后,当访问拦截被拦截,也会快速跳转到目标网页。

如上可行的实现基础是这样子

  1. Chrome插件有能力在网页上下文下执行指定脚本
  2. 查看微信拦截网页源码,发现JS上下文中存在对象cgiData,而cgiData.url存储了目标网页地址,因此只要确保网页DCL后,脚本直接执行跳转目标网页即可。

问题到这里已经解决,但是这个方案有些许不足,整个跳转逻辑是在网页加载后,因此用户还是会揉眼可见这个跳转过程

如果想继续提升体验🚀,是否有更好的方案呢?YES!

MiTM(中间人攻击)-浏览器代理

上述方案弊端是处理是在浏览器网页完全加载后进行,如果增加代理,在微信返回的响应体HTML在到达浏览器之前就在代理层面解析,拿到cgiData.url,然后构造重定向请求响应,使其重定向到Location: cgiData.url,不就解决了吗?是的。

同时注意,微信拦截网址是HTTPS,因此想要解析,还需要代理支持MiTM,否则只可以看到域名,无法解析具体请求参数。

确定了如上解决思路,具体只剩下实现了。

代理App有很多,比如Charles/Surge/Whistle,平时使用Surge多些,所以这里就尝试使用Surge解决。

  1. 开启系统代理,从而确保Chrome走代理

  2. 开启MiTM,增加weixin110.qq.com域名,测试开启生效的办法是,访问拦截网页,点击证书发现变成Surge签发的即OK

  3. 增加模块,编写脚本,从而实现重定向。该脚本模块我已开源,不想了解具体实现的直接安装即可。

    跳转脚本如下:

   /**
    * 获取微信拦截网页中目标网页地址,直接返回重定向
    */
   
   (function redirectUrl() {
     try {
       let cgiData = $response.body.match(/(?="url":").+(?=","btns)/)[0];
       cgiData = cgiData.substring(7).replace(new RegExp('/', 'g'), '/');
       $done({
         headers: {
           Location: cgiData
         },
         status: 301
       });
     } catch (e) {
       $done({});
     }
   })();

如上操作后,再次在微信中点击网址,就会直接跳转目标网页,相较之前体验更好些了。

回顾下该方案的实现基础是这样子

  1. 系统代理App确保请求/响应都会经过软件,因此也就有机会可以处理
  2. MiTM解决HTTPS的解析
  3. 代理App获取/修改请求响应

对比来看,方案2体验明显更好些,当然成本也更高,因为你需要在代理App层面做这些设定才可以解决。

除此之外,虽然这个方案可以解决问题,但要了解,MiTM并非永远work,如果一个网页安全升级,增加了HPKP/Certificate Pining,那么就可能会遇到MiTM failed,比如Apple AppStore商店的搜索服务,当开启MiTM时会发现失败,请求无法正常响应了。索幸大多数站点并没有开启该功能,比如这里的微信拦截服务。

HPKP

HPKP由于各种原因,浏览器现在都放弃了支持,更多存在于面向非网页服务里

比如nginx下想实现可以进行如下设定

add_header Public-Key-Pins 'pin-sha256="YLh1dUR9y6Kja30RrAn7JKnbQG/uEtLMkBgFF2Fuihg="; pin-sha256="klO23nT2ehFDXCfx3eHTDRESMz3asj1muO+4aIdjiuY="; max-age=2592000; includeSubDomains';

完整操作步骤,可查看这里

写在最后

done。