webview http劫持的一點攔截 擷取host方法 matcher.group理解
阿新 • • 發佈:2019-01-08
先來了解下常見的網路劫持:
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;
}
}
}