1. 程式人生 > >webview http劫持的一點攔截 擷取host方法 matcher.group理解

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;
        }
    }
}