前端页面劫持和反劫持
前端頁面劫持和反劫持
頁面劫持
使用HTTP請求請求一個網(wǎng)站頁面的時候,網(wǎng)絡(luò)運(yùn)營商會在正常的數(shù)據(jù)流中插入精心設(shè)計(jì)的網(wǎng)絡(luò)數(shù)據(jù)報文,讓客戶端(通常是瀏覽器)展示“錯誤”的數(shù)據(jù),通常是一些彈窗,宣傳性廣告或者直接顯示某網(wǎng)站的內(nèi)容。
常見劫持手段
跳轉(zhuǎn)型劫持:
用戶輸入地址A,但是跳轉(zhuǎn)到地址B
為了獲取流量,一些電商或者類似百度這樣需要流量合作的網(wǎng)站都會有自己的聯(lián)盟系統(tǒng),通過給予一些獎勵來獲取導(dǎo)流,比如:百度或者電商會有渠道分成。
為了區(qū)分哪些是第三方給予導(dǎo)流過來的,通常會在url地址增加類似source、from之類的參數(shù),或者進(jìn)入頁面之前通過「中間頁」種cookie。
這樣,當(dāng)用戶輸入一個正常網(wǎng)址的時候,劫持方會在網(wǎng)絡(luò)層讓其跳轉(zhuǎn)到帶分成或者渠道號的「中間頁」或者帶渠道號的頁面。這樣用戶進(jìn)行下單或者搜索等行為,劫持方會得到「傭金」。
DNS劫持:在DNS服務(wù)器中,將www.xxx.com的域名對應(yīng)的IP地址進(jìn)行了變化。你解析出來的域名對應(yīng)的IP,在劫持前后不一樣;
- 地址欄輸入freebuf.com
- 訪問本機(jī)的hosts文件,查找 freebuf.com 所對應(yīng)的 IP,若找到,則訪問該IP
- 若未找到,則進(jìn)行這一步,去(遠(yuǎn)程的)DNS服務(wù)器上面找freebuf.com 的IP,訪問該IP
中間人劫持就發(fā)生在第三步:由于惡意攻擊者控制了你的網(wǎng)關(guān),當(dāng)你發(fā)送了一個查找freebuf.com的IP的請求的時候,中間人攔截住,并返回給你一個惡意網(wǎng)址的IP,你的瀏覽器就會把這個IP當(dāng)做你想要訪問的域名的IP!!這個IP是攻擊者搭建的一個模仿了目標(biāo)網(wǎng)站前端界面的界面,當(dāng)你在該界面輸入用戶名密碼或者付款操作的時候,就會中招。
注入型劫持:
有別于跳轉(zhuǎn)型型劫持,指通過在正常的網(wǎng)頁中注入廣告代碼(js、iframe等),實(shí)現(xiàn)頁面彈窗提醒或者底部廣告等,又分為下面三個小類:
1.注入js類劫持:
在正常頁面注入劫持的js代碼實(shí)現(xiàn)的劫持;注入js的方式可以通過 document.write或者直接改html代碼片段等方式,給頁面增加外鏈js,為了做到更難檢測,有些運(yùn)營商會捏造一個不存在的url地址,從而不被過濾或者檢測。
案例1:運(yùn)營商會用自己識別的ip或者域名做js網(wǎng)址,wap.zjtoolbar.10086.cn這類只有在浙江移動網(wǎng)絡(luò)下才會被解析出來,同理ip也是
案例2:運(yùn)營商很聰明,知道頁面可以檢測所有外鏈js的域名,比如:m.baidu.com我只允許m.baidu.com/static的外鏈js,其他js都會被記錄反饋;為了不被檢測出來,我遇見個case電信會訪問一個不存在的地址,比如:m.baidu.com/static/abc.js,這個地址在運(yùn)營商直接返回劫持的js代碼,請求不會發(fā)到百度的服務(wù)器。
2.iframe類劫持:
將正常頁面嵌入iframe或者頁面增加iframe頁面;一般是通過熱門關(guān)鍵詞之類做SEO,打開網(wǎng)站實(shí)際去了廣告之類沒有任何實(shí)際內(nèi)容,而頁面卻是內(nèi)嵌了一個其他網(wǎng)站,我們要是識別出來不被內(nèi)嵌就需要檢測。
3.篡改頁面類劫持:
正常頁面出現(xiàn)多余的劫持網(wǎng)頁標(biāo)簽,導(dǎo)致頁面整體大小發(fā)生變化;
HTTP劫持:標(biāo)識HTTP連接。在天上飛的很多連接中,有許多種協(xié)議,第一步做的就是在TCP連接中,找出應(yīng)用層采用了HTTP協(xié)議的連接,進(jìn)行標(biāo)識;篡改HTTP響應(yīng)體,可以通過網(wǎng)關(guān)來獲取數(shù)據(jù)包進(jìn)行內(nèi)容的篡改;搶先回包,將篡改后的數(shù)據(jù)包搶先正常站點(diǎn)返回的數(shù)據(jù)包先到達(dá)用戶側(cè),這樣后面正常的數(shù)據(jù)包在到達(dá)之后會被直接丟棄。
劫持檢測方法
1、跳轉(zhuǎn)型劫持
跳轉(zhuǎn)型劫持如果用單純靠Web頁面進(jìn)行檢測比較困難,當(dāng)時我們做檢測是在手機(jī)百度(手百)內(nèi)做檢測,所以比較簡單,用戶輸入搜索詞(query),打開百度的頁面URL,然后當(dāng)頁面加載結(jié)束,APP對比訪問的URL是否是之前要訪問的URL,如果URL不一致,則記錄上報。
2、注入js類頁面
- 改寫 document.write方法
- 遍歷頁面 script標(biāo)簽,給外鏈js增加白名單,不在白名單內(nèi)js外鏈都上報
- 重寫 Element.prototype.setAttribute,我們發(fā)現(xiàn)這里用到了 setAttribute 方法,如果我們能夠改寫這個原生方法,監(jiān)聽設(shè)置 src 屬性時的值,通過黑名單或者白名單判斷它,就可以判斷該標(biāo)簽的合法性了。
MutationObserver 是 HTML5 新增的 API,功能很強(qiáng)大,給開發(fā)者們提供了一種能在某個范圍內(nèi)的 DOM 樹發(fā)生變化時作出適當(dāng)反應(yīng)的能力。就是 MutationObserver 在觀測時并非發(fā)現(xiàn)一個新元素就立即回調(diào),而是將一個時間片段里出現(xiàn)的所有元素,一起傳過來。所以在回調(diào)中我們需要進(jìn)行批量處理。而且,其中的 callback 會在指定的 DOM 節(jié)點(diǎn)(目標(biāo)節(jié)點(diǎn))發(fā)生變化時被調(diào)用。在調(diào)用時,觀察者對象會傳給該函數(shù)兩個參數(shù),第一個參數(shù)是個包含了若干個 MutationRecord 對象的數(shù)組,第二個參數(shù)則是這個觀察者對象本身。
var observer = new MutationObserver(function (mutations, observer) {mutations.forEach(function(mutation) {console.log(mutation);}); });var article = document.querySelector('article');var options = {'childList': true,'attributes':true } ;observer.observe(article, options); // 保存原有接口 var old_setAttribute = Element.prototype.setAttribute;// 重寫 setAttribute 接口 Element.prototype.setAttribute = function(name, value) {// 匹配到 <script src='xxx' > 類型if (this.tagName == 'SCRIPT' && /^src$/i.test(name)) {// 白名單匹配if (!whileListMatch(whiteList, value)) {console.log('攔截可疑模塊:', value);return;}}// 調(diào)用原始接口old_setAttribute.apply(this, arguments); };// 建立白名單 var whiteList = [ 'www.yy.com', 'res.cont.yy.com' ];/*** [白名單匹配]* @param {[Array]} whileList [白名單]* @param {[String]} value [需要驗(yàn)證的字符串]* @return {[Boolean]} [false -- 驗(yàn)證不通過,true -- 驗(yàn)證通過]*/ function whileListMatch(whileList, value) {var length = whileList.length,for (i = 0; i < length; i++) {// 建立白名單正則var reg = new RegExp(whiteList[i], 'i');// 存在白名單中,放行if (reg.test(value)) {return true;}}return false; }3、檢測是否被iframe嵌套
window.self:返回一個指向當(dāng)前 window 對象的引用。
window.top:返回窗口體系中的最頂層窗口的引用。
4、特殊方法
前面提到類似電信捏造在白名單內(nèi)的js URL和篡改頁面內(nèi)容的,我們用上面提到的方法檢測不到這些信息,如果是在APP內(nèi),可以做的事情就比較多了,除了上面之外,還可以比較頁面的 content-length。當(dāng)時手百的做法是:
在用戶開始輸入query的時候,APP訪問一個空白頁面,頁面內(nèi)只有html、title、head、body、script,而script標(biāo)簽內(nèi)主要代碼就是嗅探是否被劫持。
因?yàn)橐话憬俪植粫槍δ硞€頁面,而是針對整個網(wǎng)站域名,所以我們的空白頁面也會被劫持。
劫持防御
最簡單粗暴的就是直接上 HTTPS,一勞永逸。再就是取證,去打官司或者警告渠道作弊者。除此之外,我們還可以繼續(xù)利用空白頁面做劫持檢測。
手百在沒有全量https時期(畢竟全站https牽扯的工作量不小),利用空白頁面嗅探出當(dāng)前網(wǎng)絡(luò)環(huán)境存在劫持風(fēng)險的時候,那么就通過調(diào)用客戶端的接口,告訴客戶端本次啟動期間使用 https,這樣既可以降低劫持風(fēng)險,又可以通過這個頁面小流量測試https數(shù)據(jù),將來https全量后,還可以通過空白頁面將老版本的APP全量打開https
總結(jié)
以上是生活随笔為你收集整理的前端页面劫持和反劫持的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: jquery.uploadify php
- 下一篇: 暴风影音