利用中间人拦截实现APP内H5窜改

背景

公司与某银行合作,由我公司开发一个H5页面嵌入到该银行的官方APP中,业务场景为用户在H5中定位获取附近商户门店,然后用户在H5上领优惠券然后去线下门店核销优惠券。

当我们开发进度过半时,尽管一催再催,银行方面却一直迟迟未将测试环境APP提供给我们。由于担心如果银行方面在临近交付时才提供测试环境APP,会影响到H5在APP中的兼容性测试,于是我提出了使用该银行生产环境的APP来做兼容性测试。

实际操作就是通过抓包工具例如Charles做中间人拦截,把官方APP中任意一个H5页面窜改为我们需要测试的H5页面,然后就实现了在该银行APP中测试H5的兼容性了。当然由于测试环境跟生产环境的登录数据隔离,需要做一些额外的处理例如通过中间人拦截修改报文数据来保证业务流程能不阻塞。

Android抓包总结

拦截替换页面

这次示例中挑中被窜改的H5为下图中的话费充值页面,正常情况下,用户单击该按钮后,APP会跳转到话费充值的H5页面。

image

image

打开Charles抓包工具,开始分析手机的所有HTTP请求,最后定位到图中的域名为wap.007ka.cnGET请求就是我们准备窜改的话费充值H5页面。

image

Charles可以对指定请求打断点,然后对该请求进行报文窜改。如图,可以直接右击该请求,点击Breakpoints对该请求打断点,也可以在菜单栏点击Proxy-Breakpoint Settings按钮,由用户自定义输入需要打断点的域名、端口号、Path的HTTP请求。

image

image

断点设置完成后,重新在APP中点击充值话费入口按钮,APP显示请求被阻塞,而Charles则弹出断点界面,由用户选择是否放行该请求,亦或者是窜改改报文、取消请求。

由于设置的断点是Request & Response,所以会将一个HTTP的请求报文和返回报文都会断点一次,如下两张图。对于Request点击Execute按钮放行,不做任何修改,而对于Response,则进入Edit Response界面修改返回报文,将原先的200状态码报文修改为302重定向,而重定向地址则为需要测试的H5链接。

image

image

image

Response的报文窜改为302重定向后,点击Execute按钮放行,这时APP则成功跳转到我们预期的待测试H5页面,即实现了中间人拦截,并将原先的话费充值页面窜改替换了成了我们开发的H5页面。

image

安卓手机定位失效

在通过上述操作成功在该银行生产环境APP中测试我司测试环境H5后,测试进度稳定进行,然后发现了一个问题:手机定位获取在安卓APP环境失效,而苹果APP环境正常。该H5用的是高德定位,几个前端开发反复Review代码后并没有发现明显的错误逻辑,最终怀疑是否是银行安卓APP对定位有特殊限制。

与银行开发人员交涉未果后,我便通过抓包看看该银行APP的其他已上线业务功能的H5页面,尝试能不能看到其他H5是如何成功获取到定位信息。结果竟然真找到一个没有做JS代码混淆的H5页面,并在中找到如下的定位逻辑:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
if(isWeixin()){ //微信 高德定位
getLocation();// 获取定位
}else{
var u = navigator.userAgent;
if(u.indexOf('Android') > -1 || u.indexOf('Linux') > -1){ //安卓

window.SysClientJs.getNearByDotLocation("getLongitudeAndLatitude");

setTimeout(function(){
if(!androidOkFlag){
onError();
}
},6000);

}else if(u.indexOf('iPhone') > -1){ //ios

// setWebitEvent('getLongitudeAndLatitude','361')
getLocation();// 获取定位
}
}

然后与前端开发同学猜测的一样,安卓APP环境的定位获取需要特殊处理,需要调用APP的JSDK。看到这块代码,我们真的是欲言又止,银行方面从需求到开发,至始至终没有提过APP中有JSDK的存在,浪费了我们这么多时间纠结定位失效的问题。

最终前端同学直接模仿这现成的代码,在安卓APP环境成功获取定位信息。