XSS的中文名稱叫跨站腳本,是WEB漏洞中比較常見的一種,特點就是可以將惡意HTML/JavaScript代碼注入到受害用戶瀏覽的網頁上,從而達到劫持用戶會話的目的,XSS根據惡意腳本的傳遞方式可以分為3種,分別為反射型、存盤型、DOM型,前面兩種惡意腳本都會經過服務器端然后回傳給客戶端,相對DOM型來說比較好檢測與防御,而DOM型不用將惡意腳本傳輸到服務器在回傳客戶端,這就是DOM型和反射、存盤型的區別,所以我這里就單獨的談一下DOM型XSS,
DOM檔案
為了更好的理解DOM型XSS,先了解一下DOM,畢竟DOM型XSS就是基于DOM檔案物件模型的,對于瀏覽器來說,DOM檔案就是一份XML檔案,當有了這個標準的技術之后,通過JavaScript就可以輕松的訪問它們了,
下面舉例一個DOM將HTML代碼轉化成樹狀結構:
<html>
<head>
<meta charset="gbk" />
<title> TEST </title>
</head>
<body>
<p>The is p.<p>
<h1>Product:</h1>
<ul>
<li>Apple</li>
<li>Pear</li>
<li>Corn</li>
</ul>
</body>
</html>
轉化成模型如下圖:

這樣做的好處就是,通過這種簡單的樹狀結構,就能把元素之間的關系簡單明晰的表示出來,方便客戶端的JavaScript腳本通過DOM動態的檢查和修改頁面內容,不依賴服務端的資料,
利用原理
客戶端JavaScript可以訪問瀏覽器的DOM文本物件模型是利用的前提,當確認客戶端代碼中有DOM型XSS漏洞時,并且能誘使(釣魚)一名用戶訪問自己構造的URL,就說明可以在受害者的客戶端注入惡意腳本,利用步驟和反射型很類似,但是唯一的區別就是,構造的URL引數不用發送到服務器端,可以達到繞過WAF、躲避服務端的檢測效果,
為了更方便大家的理解,下面我舉幾個場景給大家理解,
場景一:innerHTML
<html>
<head>
<title> DOM-XSS TEST </title>
<style>
#box{width:250px;height:200px;border:1px solid #e5e5e5;background:#f1f1f1;}
</style>
</head>
<body>
<script>
window.onload= function(){
var oBox=document.getElementById("box");
var oSpan=document.getElementById("span1");
var oText=document.getElementById("text1");
var oBtn=document.getElementById("Btn");
oBtn.onclick = function(){
oBox.innerHTML = oBox.innerHTML + oSpan.innerHTML + oText.value + "<br/>";
// oBox.innerHTML += oSpan.innerHTML + oText.value + "<br/>";//這是簡便的寫法,在js中 a=a+b ,那么也等同于 a+=b
oText.value=""
};
}
</script>
<div id="box"></div>
<span id="span1">小明:</span>
<input type="text" id="text1"/>
<input id="Btn" type="button" value="https://www.cnblogs.com/mysticbinary/p/發送訊息" name=""/>
</body>
</html>
第一次是正常訪問:
hellow
第二次是將JavaScript代碼作為引數寫入值中:
<svg/onload=alert(1)>

這里我只在火狐瀏覽器利用成功,在chrome利用失敗,我猜可能chrome對安全防護做得比較好,這里不繼續各個瀏覽器版本問題,
使用innerHTML、outerHTML 時要注意,標簽需不進行編碼處理,可能會導致XSS,防護方法就是替換成innerText,它自動將HTML標簽決議為普通文本,所以HTML標簽不會被執行,避免XSS攻擊,
oBox.innerText = oBox.innerHTML + oSpan.innerHTML + oText.value + "<br/>";
場景二:跳轉
<html>
<head>
<title> DOM-XSS TEST </title>
</head>
<body>
<script>
var hash = location.hash;
if(hash){
var url = hash.substring(1);
location.href = https://www.cnblogs.com/mysticbinary/p/url;
}
</script>
