关闭恼人的微信网址拦截

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

Tampermonkey浏览器插件

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

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

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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    // ==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. 增加模块,编写脚本,从而实现重定向。该脚本模块我已开源,不想了解具体实现的直接安装即可。

    跳转脚本如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/**
* 获取微信拦截网页中目标网页地址,直接返回重定向
*/

(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下想实现可以进行如下设定

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

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

写在最后

done。