webview http劫持的一点拦截 截取host方法 matcher.group理解

先来了解下常见的网络劫持:

  • dns劫持(域名劫持)
    现象就是用户不能访问目的网址或访问的是假网址。

  • http劫持
    现象就是用户访问的看到的页面可能是被恶意修改过的,比如常见的在底部弹出宣传性的广告或者直接某网站的内容。本质是在正常的数据流中插入精心设计的网络数据报文,目的是让用户端程序解释“错误”的数据。

以前做的一款App,今天被客户方投诉在上海地区出现了打开网页后接着跳转某赌博App的appstore页面或展示了宣传赌博app的网页。看了客户方提供的视频,发现是先展示出了目的页面后面才发生的跳转错误页,很明显这不是dns劫持而是http劫持了。
发生劫持的M站的确是使用的http协议,发生事故后客户方目前已在部署ssl证书着手改为https协议(披着ssl安全协议的http)。
今天我想讲的是,如果针对的是数据流中添加了跳转恶意链接的劫持行为的话,作为webview载体方来说,还是可以稍微做一下拦截的。
记得在之前写的文章《h5 App通信 轻量级方式》中就提到过这个api:

@SuppressWarnings("deprecation")
@Override
public boolean shouldOverrideUrlLoading(WebView view, String urlConection) {
if (urlConection.toLowerCase().startsWith("http:") || urlConection.toLowerCase().startsWith("https:")) {
     //TODO  host白名单限制
    webview.loadUrl(urlConection);
    return true;
  }
  return true;
}

@Override
public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
    return super.shouldOverrideUrlLoading(view, request);
}
java  截取url中host的方法
public static  String getHost(String url){
      Pattern pattern = Pattern.compile("^http[s]?:\\/\\/(.*?)([:\\/]|$)");// 匹配的模式
      Matcher m = pattern.matcher(url);
       while (m.find()) {
            return m.group(1);
        }
        return "";
    }
在正则表达式中:
(pattern)
=》匹配pattern并获取这一匹配。所获取的匹配可以从产生的Matches集合得到。
.
=> 匹配除“\n”和"\r"之外的任何单个字符  
*
=> 匹配前面的子表达式任意次,等价于{0,}。
?
=> 匹配前面的子表达式零次或一次,等价于{0,1}。
注:当该字符紧跟在任何一个其他限制符(*,+,?,{n},{n,},{n,m})后面时,匹配模式是非贪婪的。非贪婪模式尽可能少地匹配所搜索的字符串,而默认的贪婪模式则尽可能多地匹配所搜索的字符串。例如,对于字符串“oooo”,“o+”将尽可能多地匹配“o”,得到结果[“oooo”],而“o+?”将尽可能少地匹配“o”,得到结果 ['o', 'o', 'o', 'o']

代码分析:
正则表达式 "^http[s]?:\\/\\/(.*?)([:\\/]|$)"
getHost("http://www.baidu.com:8090/path?y=90&https://www1.baidu.com:8090/path?y=39&https://www2.baidu.com:8090/path?y=19")
m.group(0) 输出 http://www.baidu.com:
m.group(1) 输出 www.baidu.com
m.group(2) 输出 :
根据以上我们可以看出Matcher的group方法,入参的Index的意义:
Index为0 ,代表符合匹配的整体字符串
Index为1 ,代表符合第一个子匹配的字符串 正则中第一个()
Index为2 ,代表符合第二个子匹配的字符串 正则中第二个()

有了上面的方法后,我们就能采用一些白名单限制的措施了。
不在白名单内的话, 就直接return true 不执行webview.loadUrl。

再提供下js的写法
let reg = /http[s]?:\/\/(.*?)([:\/]|$)/ 
let result=reg.exec(getUrl)
let whiteUrl = [ 'xx', 'xxx', 'xxx']
let flag=0;// 是否在白名单内
if(result){
    for(let i=0,l=whiteUrl.length;i<l;i++){
        if(whiteUrl[i]==result[1]){
            flag=1;
            break;
        }
    }
}
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
WebView拦截http链接,例如file://、tel://、mailto://等,可以通过重写shouldOverrideUrlLoading方法来实现。以下是示例代码: ```java webView.setWebViewClient(new WebViewClient() { @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { if (url.startsWith("http") || url.startsWith("https")) { // 如果链接以httphttps开头,则继续加载链接 return false; } else { // 如果链接不是以httphttps开头,则拦截链接并处理 if (url.startsWith("tel:")) { // 如果链接以tel:开头,则打电话 Intent intent = new Intent(Intent.ACTION_DIAL, Uri.parse(url)); startActivity(intent); } else if (url.startsWith("mailto:")) { // 如果链接以mailto:开头,则发送邮件 Intent intent = new Intent(Intent.ACTION_SEND); intent.setType("message/rfc822"); intent.putExtra(Intent.EXTRA_EMAIL, new String[]{url.substring(7)}); startActivity(Intent.createChooser(intent, "Send Email")); } else if (url.startsWith("file:")) { // 如果链接以file:开头,则打开本地文件 Intent intent = new Intent(Intent.ACTION_VIEW); intent.setDataAndType(Uri.parse(url), "application/pdf"); startActivity(intent); } return true; } } }); ``` 在上面的示例,我们首先检查链接是否以httphttps开头。如果是,则继续加载链接。如果链接不是以httphttps开头,则根据链接的协议进行相应的处理。例如,如果链接以"tel:"开头,则打电话;如果链接以"mailto:"开头,则发送邮件;如果链接以"file:"开头,则打开本地文件。最后,返回true以拦截链接。 请注意,如果您需要在Android 7.0及更高版本上拦截HTTP链接,建议您使用shouldOverrideUrlLoading(WebView view, WebResourceRequest request)方法,因为shouldOverrideUrlLoading(WebView view, String url)方法在7.0及更高版本上已经过时。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值