移動端H5防劫持(防止廣告注入)
最近項目中自己的H5網(wǎng)頁出現(xiàn)了被劫持插入廣告的事件歇式,看好趁著這個節(jié)點整理下H5被劫持的原因及防止劫持的方法咳榜。
原因:
經(jīng)過查找和調(diào)研市面上出現(xiàn)這種情況的原因大概分為三種:
1.DNS劫持(也就是運營商搞的鬼)
2.http劫持(此類情況最多)
3.項目中使用第三方的jar包
首先定位我們自己出現(xiàn)此類問題應(yīng)該從以下幾個方面查找除抛、調(diào)試:
1.網(wǎng)絡(luò)用的是4g還是wifi昵慌?
2.如果是wifi,是不是路邊免費的wifi无宿?
3.在什么頁面出現(xiàn)日矫?(方便定位是h5頁面還是原生界面赂弓,對大部分用戶,千萬不要問他是h5還是原生哪轿,只能自己分析盈魁,如果原生界面也出現(xiàn)那么第三方j(luò)ar出現(xiàn)問題的概率很大,如果只是h5界面窃诉,那么劫持的可能性很大)
4.使用的是android還是ios客戶端
什么是DNS劫持:
首先DNS是什么备埃。在因特網(wǎng)中,機器相互識別靠的是ip褐奴,而ip單純的無意義數(shù)字的結(jié)合按脚,很難被人類熟記,所以產(chǎn)生了域名敦冬,例如[www.baidu.com](https://link.juejin.im/?target=http%3A%2F%2Fwww.baidu.com%2F)?就是域名辅搬。那么問題來了,我們輸入域名,機器又不認(rèn)識堪遂,那么機器怎么去訪問介蛉?那么就輪到DNS出場了,DNS在作為域名和IP地址相互映射的一個分布式數(shù)據(jù)庫溶褪,就是我們的瀏覽器币旧,會將域名拿到DNS去解析出ip地址來訪問,DNS劫持是指在劫持的網(wǎng)絡(luò)范圍內(nèi)攔截域名解析的請求猿妈,分析請求的域名吹菱,把審查范圍以外的請求放行,否則返回假的IP地址或者什么都不做使請求失去響應(yīng)彭则,其效果就是對特定的網(wǎng)絡(luò)不能反應(yīng)或訪問的是假網(wǎng)址鳍刷。
通俗來說,就是他給我們指向了另一個地址俯抖,或者讓我們無法訪問输瓜。電信以前的互聯(lián)星空的,每次聯(lián)網(wǎng)打開的第一個網(wǎng)頁永遠(yuǎn)是互聯(lián)星空芬萍。就是典型的DNS劫持尤揣。
什么是http劫持:
百度百科的說法:HTTP劫持是在使用者與其目的網(wǎng)絡(luò)服務(wù)所建立的專用數(shù)據(jù)通道中,監(jiān)視特定數(shù)據(jù)信息柬祠,提示當(dāng)滿足設(shè)定的條件時北戏,就會在正常的數(shù)據(jù)流中插入精心設(shè)計的網(wǎng)絡(luò)數(shù)據(jù)報文,目的是讓用戶端程序解釋“錯誤”的數(shù)據(jù)瓶盛,并以彈出新窗口的形式在使用者界面展示宣傳性廣告或者直接顯示某網(wǎng)站的內(nèi)容最欠。
通俗來說示罗,你要去百度的首頁惩猫,他會給你百度首頁,然后再百度首頁的某個部位+個廣告蚜点。 更具欺騙性轧房,危害更大。
解決方案:
1.使用https請求替換http請求绍绘,可以有效的防止劫持奶镶。原理是:因為SSl協(xié)議唉http請求開始前增加了握手階段:
在SSL握手階段,客戶端瀏覽器會認(rèn)證服務(wù)器的身份陪拘,這是通過“證書”來實現(xiàn)的厂镇,證書由證書權(quán)威(CA)為某個域名簽發(fā),可以理解為網(wǎng)站的身份證件左刽,客戶端需要對這個證件進(jìn)行認(rèn)證捺信,需要確定該證書是否屬于目標(biāo)網(wǎng)站并確認(rèn)證書本身是否有效。最后在握手階段欠痴,通信的雙方還會協(xié)商出一個用于加密和解密的會話密鑰迄靠。
SSL握手階段結(jié)束之后秒咨,服務(wù)器和客戶端使用協(xié)商出的會話密鑰對交互的數(shù)據(jù)進(jìn)行加密/解密操作,對于HTTP協(xié)議來說掌挚,就是將HTTP請求和應(yīng)答經(jīng)過加密之后再發(fā)送到網(wǎng)絡(luò)上雨席。
2.H5處理:
嵌入的代碼基本都是iframe,把以下js代碼加入 body標(biāo)簽內(nèi)吠式,以刪除iframe(記得用script標(biāo)簽包裹)
//以下代碼為刪除嵌入廣告
var del_times = 0, deTimer = null;
function adGo() {
? ? var iframe = document.getElementsByTagName('iframe')[0];
? ? if(iframe){
? ? ? ? console.log(iframe)
? ? ? ? //循環(huán) iframe 父類陡厘,直到找到body和body的下一級,然后整個嵌入的代碼刪除奇徒。
? ? ? ? var bodyNode = {tagName:''}, iframeParent, targetNode = iframe.parentNode;
? ? ? ? while (bodyNode.tagName != 'BODY'){
? ? ? ? ? ? bodyNode = targetNode;
? ? ? ? ? ? if(bodyNode.tagName != 'BODY'){
? ? ? ? ? ? ? ? iframeParent = targetNode;
? ? ? ? ? ? ? ? targetNode = targetNode.parentNode;
? ? ? ? ? ? }
? ? ? ? }
? ? ? ? if(iframeParent) //如果iframe有父類
? ? ? ? ? ? bodyNode.removeChild(iframeParent);
? ? ? ? else
? ? ? ? ? ? bodyNode.removeChild(iframe);
? ? }
? ? del_times++;
? ? if (del_times > 10) window.clearInterval(deTimer)
}
deTimer = self.setInterval(adGo, 1000);? //把這個1000, 調(diào)低一點雏亚,比如200