1. 程式人生 > 其它 >Web安全學習筆記 XSS上

Web安全學習筆記 XSS上

Web安全學習筆記 XSS上

繁枝插雲欣 ——ICML8


  1. XSS的分類和基本認識
  2. XSS的危害
  3. 同源策略的基本認識

一.XSS的分類和基本認識

1. 簡介

XSS全稱為Cross Site Scripting,為了和CSS分開簡寫為XSS,中文名為跨站指令碼。該漏洞發生在使用者端,是指在渲染過程中發生了不在預期過程中的JavaScript程式碼執行。XSS通常被用於獲取Cookie以受攻擊者的身份進行操作等行為。

2. 分類

1.反射型XSS

反射型XSS是比較常見和廣泛的一類,舉例來說,當一個網站的程式碼中包含類似下面的語句:

<?php echo "<p>hello, $_GET['user']</p>";?> 

那麼在訪問時設定

/?user=</p><script>alert("hack")</script><p>

則可執行預設好的JavaScript程式碼。

反射型XSS通常出現在搜尋等功能中,需要被攻擊者點選對應的連結才能觸發,且受到XSS Auditor、NoScript等防禦手段的影響較大。

2.儲存型XSS

儲存型XSS相比反射型來說危害較大,在這種漏洞中,攻擊者能夠把攻擊載荷存入伺服器的資料庫中,造成持久化的攻擊

3.DOM XSS

DOM型XSS不同之處在於DOM型XSS一般和伺服器的解析響應沒有直接關係,而是在JavaScript指令碼動態執行的過程中產生的

例如

<html>
<head>
<title>DOM Based XSS Demo</title>
<script>
function xsstest()
{
    var str = document.getElementById("input").value;
    document.getElementById("output").innerHTML = "<img src='"+str+"'></img>";
}
</script>
</head>
<body>
<div id="output"></div>
<input type="text" id="input" size=50 value="" />
<input type="button" value="submit" onclick="xsstest()" />
</body>
</html>

輸入

x' onerror='javascript:alert(/xss/)

即可觸發

4.Blind XSS

Blind XSS是儲存型XSS的一種,它儲存在某些儲存中,當一個“受害者”訪問這個頁面時執行,並且在文件物件模型(DOM)中呈現payload。 它被稱為Blind的原因是因為它通常發生在通常不暴露給使用者的功能上。


二.XSS的危害

存在XSS漏洞時,可能會導致以下幾種情況:

1.使用者的Cookie被獲取,其中可能存在Session ID等敏感資訊。

若伺服器端沒有做相應防護,攻擊者可用對應Cookie登陸伺服器。

2.攻擊者能夠在一定限度內記錄使用者的鍵盤輸入。

3.攻擊者通過CSRF等方式以使用者身份執行危險操作。

4.XSS蠕蟲。

5.獲取使用者瀏覽器資訊。

6.利用XSS漏洞掃描使用者內網。


三.同源策略的基本認識


1. 簡介

同源策略限制了不同源之間如何進行資源互動,是用於隔離潛在惡意檔案的重要安全機制。 是否同源由URL決定,URL由協議、域名、埠和路徑組成,如果兩個URL的協議、域名和埠相同,則表示他們同源。

1.1. file域的同源策略

在之前的瀏覽器中,任意兩個file域的URI被認為是同源的。本地磁碟上的任何HTML檔案都可以讀取本地磁碟上的任何其他檔案。

從Gecko 1.9開始,檔案使用了更細緻的同源策略,只有當原始檔的父目錄是目標檔案的祖先目錄時,檔案才能讀取另一個檔案。

1.2. cookie的同源策略

cookie使用不同的源定義方式,一個頁面可以為本域和任何父域設定cookie,只要是父域不是公共字尾(public suffix)即可。

不管使用哪個協議(HTTP/HTTPS)或埠號,瀏覽器都允許給定的域以及其任何子域名訪問cookie。設定 cookie時,可以使用 domain / path / secure 和 http-only 標記來限定其訪問性。

所以 https://localhost:8080/ 和 http://localhost:8081/ 的Cookie是共享的。

1.3. Flash/SilverLight跨域

瀏覽器的各種外掛也存在跨域需求。

通常是通過在伺服器配置crossdomain.xml

設定本服務允許哪些域名的跨域訪問

客戶端會請求此檔案,如果發現自己的域名在訪問列表裡,就發起真正的請求,否則不傳送請求。

2. 源的更改

同源策略認為域和子域屬於不同的域,例如 child1.a.coma.com/ child1.a.com child2.a.com / xxx.child1.a.com child1.a.com 兩兩不同源。

對於這種情況,可以在兩個方面各自設定 document.domain='a.com' 來改變其源來實現以上任意兩個頁面之間的通訊。

另外因為瀏覽器單獨儲存埠號,這種賦值會導致埠號被重寫為 null


3. 跨源訪問

同源策略控制了不同源之間的互動,這些互動通常分為三類:

1.通常允許跨域寫操作(Cross-origin writes)

連結(links)

重定向

表單提交

2.通常允許跨域資源嵌入(Cross-origin embedding)

3.通常不允許跨域讀操作(Cross-origin reads)

可能嵌入跨源的資源的一些示例有:

<script src="..."></script> 標籤嵌入跨域指令碼
語法錯誤資訊只能在同源指令碼中捕捉到
<link rel="stylesheet" href="..."> 標籤嵌入CSS
由於CSS的鬆散的語法規則
CSS的跨域需要一個設定
正確的Content-Type 訊息頭
<img> / <video> / <audio> 嵌入多媒體資源。
<object> <embed> 和 <applet> 的外掛。
@font-face 引入的字型
一些瀏覽器允許跨域字型( cross-origin fonts)
一些需要同源字型(same-origin fonts)
<frame> 和 <iframe> 載入的任何資源
站點可以使用X-Frame-Options訊息頭
來阻止這種形式的跨域互動

3.1. JSONP跨域

JSONP就是利用 <script> 標籤的跨域能力實現跨域資料的訪問,請求動態生成的JavaScript指令碼同時帶一個callback函式名作為引數。

服務端收到請求後,動態生成指令碼產生資料,並在程式碼中以產生的資料為引數呼叫callback函式。

JSONP也存在一些安全問題,例如當對傳入/傳回引數沒有做校驗就直接執行返回的時候,會造成XSS問題。沒有做Referer或Token校驗就給出資料的時候,可能會造成資料洩露。

另外JSONP在沒有設定callback函式的白名單情況下,可以合法的做一些設計之外的函式呼叫,引入問題。這種攻擊也被稱為SOME攻擊。

3.2. 跨源指令碼API訪問

Javascript的APIs中,如 iframe.contentWindow , window.parent , window.open window.opener 允許文件間相互引用。當兩個文件的源不同時,這些引用方式將對 window location 物件的訪問新增限制。

window 允許跨源訪問的方法有

window.blur window.close window.focus window.postMessage

window 允許跨源訪問的屬性有

window.closed window.frames window.length window.location window.opener window.parent window.self window.top window.window

其中 window.location 允許讀/寫,其他的屬性只允許讀

3. 跨源資料儲存訪問

儲存在瀏覽器中的資料,如 localStorage IndexedDB ,以源進行分割。每個源都擁有自己單獨的儲存空間,一個源中的Javascript指令碼不能對屬於其它源的資料進行讀寫操作。


4. CORS

CORS是一個W3C標準,全稱是跨域資源共享(Cross-origin resource sharing)。通過這個標準,可以允許瀏覽器讀取跨域的資源。

4.1. 常見請求頭

Origin

預檢請求或實際請求的源站URI,
瀏覽器請求預設會發送該欄位
Origin: <origin>

Access-Control-Request-Method

宣告請求使用的方法
Access-Control-Request-Method: <method>

Access-Control-Request-Headers

宣告請求使用的header欄位
Access-Control-Request-Headers: <field-name>[, <field-name>]*

4.2. 常見返回頭

Access-Control-Allow-Origin

宣告允許訪問的源外域URI
對於攜帶身份憑證的請求不可使用萬用字元 *
Access-Control-Allow-Origin: <origin> | *

Access-Control-Expose-Headers

宣告允許暴露的頭
e.g. Access-Control-Expose-Headers: X-My-Custom-Header, X-Another-Custom-Header

Access-Control-Max-Age

宣告Cache時間
Access-Control-Max-Age: <delta-seconds>

Access-Control-Allow-Credentials

宣告是否允許在請求中帶入
Access-Control-Allow-Credentials: true

Access-Control-Allow-Methods

宣告允許的訪問方式
Access-Control-Allow-Methods: <method>[, <method>]*

Access-Control-Allow-Headers

宣告允許的頭
Access-Control-Allow-Headers: <field-name>[, <field-name>]*

4.3. 防禦建議

如非必要不開啟CORS 定義詳細的白名單,不使用萬用字元,僅配置所需要的頭 配置 Vary: Origin 頭部 如非必要不使用 Access-Control-Allow-Credentials 限制快取的時間


5. 阻止跨源訪問

阻止跨域寫操作,可以檢測請求中的 CSRF token

這個標記被稱為Cross-Site Request Forgery (CSRF) 標記。

阻止資源的跨站讀取,因為嵌入資源通常會暴露資訊,需要保證資源是不可嵌入

的。但是多數情況下瀏覽器都不會遵守 Content-Type 訊息頭

例如如果在HTML文件中指定 <script> 標記

則瀏覽器會嘗試將HTML解析為JavaScript