咱們多少應該據說過一些關於web安全
的問題吧,好比http劫持
、xss跨站腳本攻擊
、corf跨站請求僞造
。當下好多的網站都沒有實現https,web安全也是一個很是重要的話題。javascript
在用戶的客戶端與其要訪問的服務器通過網絡協議協調後,兩者之間創建了一條專用的數據通道,用戶端程序在系統中開放指定網絡端口用於接收數據報文,服務器端將所有數據按指定網絡協議規則進行分解打包,造成連續數據報文。html
用戶端接收到所有報文後,按照協議標準來解包組合得到完整的網絡數據。其中傳輸過程當中的每個數據包都有特定的標籤,表示其來源、攜帶的數據屬性以及要到何處,全部的數據包通過網絡路徑中ISP的路由器傳輸接力後,最終到達目的地,也就是客戶端。前端
HTTP劫持 是在使用者與其目的網絡服務所創建的專用數據通道中,監視特定數據信息,提示當知足設定的條件時,就會在正常的數據流中插入精心設計的網絡數據報文,目的是讓用戶端程序解釋「錯誤」的數據,並以彈出新窗口的形式在使用者界面展現宣傳性廣告或者直接顯示某網站的內容。java
DNS 劫持就是經過劫持了 DNS 服務器,經過某些手段取得某域名的解析記錄控制權,進而修改此域名的解析結果,致使對該域名的訪問由原IP地址轉入到修改後的指定IP,其結果就是對特定的網址不能訪問或訪問的是假網址,從而實現竊取資料或者破壞原有正常服務的目的。web
DNS 劫持比之 HTTP 劫持 更加過度,簡單說就是咱們請求的是 http://www.a.com/index.html
,直接被重定向了 http://www.b.com/index.html
。瀏覽器
xss就是攻擊者利用漏洞,向咱們的頁面注入一些攻擊性腳本,當用戶瀏覽頁面的時候自動觸發執行,從而達到攻擊的目的。安全
HTTP 劫持 和 XSS 最終都是惡意代碼在客戶端,一般也就是用戶瀏覽器端執行,咱們應該學會即便咱們被攻擊了,咱們應該如何利用 Javascript 進行行之有效的前端防禦。bash
頁面被嵌入 iframe 中,重定向 iframe服務器
先來講說咱們的頁面被嵌入了 iframe 的狀況。也就是,網絡運營商爲了儘量地減小植入廣告對原有網站頁面的影響,一般會經過把原有網站頁面放置到一個和原頁面相同大小的 iframe 裏面去,那麼就能夠經過這個 iframe 來隔離廣告代碼對原有頁面的影響。網絡
這種狀況還比較好處理,咱們只須要知道咱們的頁面是否被嵌套在 iframe 中,若是是,則重定向外層頁面到咱們的正常頁面便可。
那麼有沒有方法知道咱們的頁面當前存在於 iframe 中呢?有的,就是 window.self 與 window.top 。
window.self
返回一個指向當前 window 對象的引用。
window.top
返回窗口體系中的最頂層窗口的引用。
複製代碼
// 咱們能夠經過以下判斷來區分是否外部被嵌套iframe
if (self != top) {
// 咱們的正常頁面
var url = location.href;
// 父級頁面重定向
top.location = url;
}
複製代碼
內聯事件及內聯腳本攔截
列出一些比較常見的注入方式:
<a href="javascript:alert(1)" ></a>
<iframe src="javascript:alert(1)" />
<img src='x' onerror="alert(1)" />
<video src='x' onerror="alert(1)" ></video>
<div onclick="alert(1)" onmouseover="alert(2)" ><div>
複製代碼
除去一些未列出來的很是少見生僻的注入方式,大部分都是 javascript:...
及內聯事件 on*
。
咱們假設注入已經發生,那麼有沒有辦法攔截這些內聯事件與內聯腳本的執行呢?
對於上面列出的 (1) (5) ,這種須要用戶點擊或者執行某種事件以後才執行的腳本,咱們是有辦法進行防護的。
以攔截 javascript:
爲例子。
// 創建關鍵詞黑名單
var keywordBlackList = [
'xss',
'BAIDU_SSP__wrapper',
'BAIDU_DSPUI_FLOWBAR'
];
document.addEventListener('click', function(e) {
var code = "";
// 掃描 <a href="javascript:"> 的腳本
if (elem.tagName == 'A' && elem.protocol == 'javascript:') {
var code = elem.href.substr(11);
if (blackListMatch(keywordBlackList, code)) {
// 註銷代碼
elem.href = 'javascript:void(0)';
console.log('攔截可疑事件:' + code);
}
}
}, true);
/** * [黑名單匹配] * @param {[Array]} blackList [黑名單] * @param {[String]} value [須要驗證的字符串] * @return {[Boolean]} [false -- 驗證不經過,true -- 驗證經過] */
function blackListMatch(blackList, value) {
var length = blackList.length,
i = 0;
for (; i < length; i++) {
// 創建黑名單正則
var reg = new RegExp(whiteList[i], 'i');
// 存在黑名單中,攔截
if (reg.test(value)) {
return true;
}
}
return false;
}
複製代碼
靜態腳本攔截
XSS 跨站腳本的精髓不在於「跨站」,在於「腳本」。
一般而言,攻擊者或者運營商會向頁面中注入一個<script>
腳本,具體操做都在腳本中實現,這種劫持方式只須要注入一次,有改動的話不須要每次都從新注入。 好比:
<div id="wrapper">
111
<script>alert('xss');</script>
</div>
複製代碼
頁面中若是有這麼一段,那麼頁面會執行alert函數。
若是是:
<div id="wrapper">
<script>alert(1)</script>
</div>
複製代碼
頁面則不會執行。
因此最廣泛的作法是轉義輸入輸出的內容,對於引號,尖括號,斜槓進行轉義
function escape(str) {
str = str.replace(/&/g, '&')
str = str.replace(/</g, '<')
str = str.replace(/>/g, '>')
str = str.replace(/"/g, '&quto;')
str = str.replace(/'/g, ''')
str = str.replace(/`/g, '`')
str = str.replace(/\//g, '/')
return str
}
複製代碼
咱們通常使用一個現成的工具:
XSS是一個用於對用戶輸入的內容進行過濾,以免遭受XSS攻擊的模塊 (什麼是XSS攻擊?)。主要用於論壇、博客、網上商店等等一些可容許用戶錄入頁面排版、 格式控制相關的HTML的場景,xss模塊經過白名單來控制容許的標籤及相關的標籤屬性, 另外還提供了一系列的接口以便用戶擴展,比其餘同類模塊更爲靈活。