关闭恼人的微信网址拦截
在微信中打开一些网页时总会出现以下拦截提醒,遇到这种情况时必须点击
继续访问
。技术人不忍这种流氓事,于是着手从技术上解决这个体验问题。
Tampermonkey浏览器插件
首先想到的是这个方案,解决步骤如下
Chrome浏览器下安装插件Tampermonkey(油猴)
插件中增加如下脚本,该脚本我已已经开源,不想了解具体实现的直接安装即可。
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);
}
})();
如上操作后,当访问拦截被拦截,也会快速跳转到目标网页。
如上可行的实现基础是这样子
- Chrome插件有能力在网页上下文下执行指定脚本
- 查看微信拦截网页源码,发现JS上下文中存在对象cgiData,而
cgiData.url
存储了目标网页地址,因此只要确保网页DCL后,脚本直接执行跳转目标网页即可。
问题到这里已经解决,但是这个方案有些许不足,整个跳转逻辑是在网页加载后,因此用户还是会揉眼可见这个跳转过程
。
如果想继续提升体验🚀,是否有更好的方案呢?YES!
MiTM(中间人攻击)-浏览器代理
上述方案弊端是处理是在浏览器网页完全加载后进行,如果增加代理,在微信返回的响应体HTML在到达浏览器之前就在代理层面解析,拿到cgiData.url,然后构造重定向请求响应,使其重定向到Location: cgiData.url
,不就解决了吗?是的。
同时注意,微信拦截网址是HTTPS,因此想要解析,还需要代理支持MiTM,否则只可以看到域名,无法解析具体请求参数。
确定了如上解决思路,具体只剩下实现了。
代理App有很多,比如Charles/Surge/Whistle,平时使用Surge多些,所以这里就尝试使用Surge解决。
开启系统代理,从而确保Chrome走代理
开启MiTM,增加
weixin110.qq.com
域名,测试开启生效的办法是,访问拦截网页,点击证书发现变成Surge签发的即OK增加模块,编写脚本,从而实现重定向。该脚本模块我已开源,不想了解具体实现的直接安装即可。
跳转脚本如下:
1 | /** |
如上操作后,再次在微信中点击网址,就会直接跳转目标网页,相较之前体验更好些了。
回顾下该方案的实现基础是这样子
- 系统代理App确保请求/响应都会经过软件,因此也就有机会可以处理
- MiTM解决HTTPS的解析
- 代理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。