HTTP劫持和DNS劫持
首先對運營商的劫持行為做一些分析,他們的目的無非就是賺錢,而賺錢的方式有兩種:
1、對正常網站加入額外的廣告,這包括網頁內浮層或彈出廣告窗口;
2、針對一些廣告聯盟或帶推廣鏈接的網站,加入推廣尾巴。例如普通訪問百度首頁,被前置跳轉為http://www.baidu.com/?tn=90509114_hao_pg
----------------------------
關於全站https必要性http流量劫持、dns劫持等相關技術 - 流風,飄然的風 - 博客園
https://www.cnblogs.com/zdz8207/p/https-framework-zatan.html
網站app被劫持怎么辦?HTTPDNS阿里雲域名防劫持, DNSPod 移動解析服務 D+ - 流風,飄然的風 - 博客園
http://www.cnblogs.com/zdz8207/p/doman-HTTPDNS-DNSPod.html
-----------------------------
在具體的做法上,一般分為DNS劫持和HTTP劫持。
DNS劫持:
一般而言,用戶上網的DNS服務器都是運營商分配的,所以,在這個節點上,運營商可以為所欲為。
例如,訪問http://xxx.qq.com/index.html,正常DNS應該返回騰訊的ip,而DNS劫持后,會返回一個運營商的中間服務器ip。訪問該服務器會一致性的返回302,讓用戶瀏覽器跳轉到預處理好的帶廣告的網頁,在該網頁中再通過iframe打開用戶原來訪問的地址。
HTTP劫持:
在運營商的路由器節點上,設置協議檢測,一旦發現是HTTP請求,而且是html類型請求,則攔截處理。后續做法往往分為2種,1種是類似DNS劫持返回302讓用戶瀏覽器跳轉到另外的地址,還有1種是在服務器返回的HTML數據中插入js或dom節點(廣告)。
在用戶角度,這些劫持的表現分為:
1、網址被無辜跳轉,多了推廣尾巴;
2、頁面出現額外的廣告(iframe模式或者直接同頁面插入了dom節點)。
-----------------------------
處理辦法:
1、先對外網做檢測,上報被劫持的情況。
對於我這個業務而言,加推廣尾巴沒意義,那么就剩下植入廣告的問題了。頁面廣告可能通過iframe方式,也可以通過dom節點方式,需要在首頁檢查這兩種情況。
window.addEventListener('DOMNodeInserted', checkDivHijack); function checkDivHijack(e) { var html = e ? (e.srcElement.outerHTML || e.srcElement.wholeText) : $('html').html(); var reg = /http:\/\/([^\/]+)\//g; var urlList = html.match(reg); if (!urlList || urlList.length == 0) { return; } reg = /^http:\/\/(.*\.qq\.com|.*\.gtimg\.cn|.*\.qlogo\.cn|.*\.qpic\.cn|.*\.wanggou\.com)\/$/; var hijack = false; for (var i = 0; i < urlList.length; i++) { if (!reg.test(urlList[i])) { hijack = true; break; } } }
(注:事后發現這個url檢查不夠嚴謹,雖然劫持的情況都能發現,但也把產品原有的一些正常插入做劫持誤報了。例如<a href="http://jiankang.qq.com" data-id="1">,不過這個是小細節,把正則表達式完善一下就ok了)
2、針對被iframe加載的情況,需要先找到運營商設置的劫持規律。
在iframe中的網頁能正常打開,而不是又被攔截加iframe,可能是因為請求的url上或cookie上運營商做了標記。我們可以利用這個規則,躲過劫持。
3、針對注入dom節點的情況,初始化時做檢查,而且后續dom注入也做檢查。可以檢查dom中是否含有白名單以外的http鏈接,如果有,就可以判定為http劫持。
4、在前端以外的處理辦法還有
a) 終端攔截所有返回包,判斷ip來自黑名單(劫持的中間ip)則丟棄返回包。
這種做法的原因是,運營商劫持http請求后,並不是完全丟棄請求包,而是做了復制,一份繼續發給目標服務器,另外一份做劫持處理直接返回302。因為這個302會比目標服務器的正常返回早得多,所以用戶瀏覽器會只認第一個302,而丟棄后到的正常返回。
如果先把第一個302丟棄,等待后續正常返回,則問題解決。
b) 終端攔截請求包,並拆包發送。
運營商一般判斷是否劫持,通過判斷是否HTTP請求。 一般只會檢測TCP連接建立后的第一個數據包,如果其是一個完整的HTTP協議才會被標記;如果並非是一個完整的HTTP協議,由於無法得到足夠多的劫持信息,所以並不會被標記為HTTP協議。
所以,只要把請求包切得足夠細,就能躲過一部分劫持(如果運營商學習“牆”大力氣做多包攔截就沒轍了)。
5、當然,最終,根本解決辦法是使用HTTPS,不過這個涉及到很多業務的修改,成本較高。如果劫持比例小,也許通過適當的補救做法會更好。
來看看檢測到的劫持情況:
總體1500萬pv的業務,一天竟然有100萬的劫持上報,即使排除一半的誤報,也代表說20個用戶中,就接近有1個用戶出現被劫持的情況。
可見,各種小運營商(尤其是移動)很黑!
各種劫持的手段都有:
1、直接返回一個帶廣告的HTML;
2、在原html中插入js,再通過js腳本安插廣告;
3、iframe展示原來正常網頁。