關於XSS

參考 www.jianshu.com/p/2d9da4490…javascript

簡述

XSS攻擊一般指的是經過利用網頁開發時留下的漏洞,經過巧妙的方法注入惡意指令代碼到網頁,使用戶加載並執行攻擊者惡意製造的網頁程序。這些惡意網頁程序一般是JavaScript,但實際上也能夠包括Java、 VBScript、ActiveX、 Flash 或者甚至是普通的HTML。攻擊成功後,攻擊者可能獲得包括但不限於更高的權限(如執行一些操做)、私密網頁內容、會話和cookie等各類內容。java

原理

HTML是一種超文本標記語言,經過將一些字符特殊地對待來區別文本和標記,例如,小於符號(<)被看做是HTML標籤的開始,之間的字符是頁面的標題等等。當動態頁面中插入的內容含有這些特殊字符(如<)時,用戶瀏覽器會將其誤認爲是插入了HTML標籤,當這些HTML標籤引入了一段JavaScript腳本時,這些腳本程序就將會在用戶瀏覽器中執行。因此,當這些特殊字符不能被動態頁面檢查或檢查出現失誤時,就將會產生XSS漏洞。express

防範

<input type="text" value="<%= escapeHTML(getParameter("keyword")) %>">
<button>搜索</button>
<div>
  您搜索的關鍵詞是:<%= escapeHTML(getParameter("keyword")) %>
</div>
複製代碼

通過了轉義函數的處理後,最終瀏覽器接收到的響應爲:瀏覽器

<input type="text" value="&quot;&gt;&lt;script&gt;alert(&#x27;XSS&#x27;);&lt;&#x2F;script&gt;">
<button>搜索</button>
<div>
  您搜索的關鍵詞是:&quot;&gt;&lt;script&gt;alert(&#x27;XSS&#x27;);&lt;&#x2F;script&gt;
</div>
複製代碼

注意特殊的 HTML 屬性、JavaScript API

<a href="<%= escapeHTML(getParameter("redirect_to")) %>">跳轉...</a>
複製代碼

這段代碼,當攻擊 URL 爲http://xxx/?redirect_to=javascript:alert('XSS'),服務端響應就成了:安全

<a href="javascript:alert(&#x27;XSS&#x27;)">跳轉...</a>
複製代碼

雖然代碼不會當即執行,但一旦用戶點擊 a 標籤時,瀏覽器會就會彈出「XSS」。bash

解決

// 根據項目狀況進行過濾,禁止掉 "javascript:" 連接、非法 scheme 等
allowSchemes = ["http", "https"];

valid = isValid(getParameter("redirect_to"), allowSchemes);

if (valid) {
  <a href="<%= escapeHTML(getParameter("redirect_to"))%>">
    跳轉...
  </a>
} else {
  <a href="/404">
    跳轉...
  </a>
}
複製代碼
  • 作了 HTML 轉義,並不等於高枕無憂。
  • 對於連接跳轉,如 <a href="xxx" 或 location.href="xxx",要檢驗其內容,禁止以 javascript: 開頭的連接,和其餘非法的 scheme。

根據上下文采用不一樣的轉義規則

把一個數據經過 JSON 的方式內聯到 HTML 中:cookie

<script>
var initData = <%= data.toJSON() %>
</script>
複製代碼

插入 JSON 的地方不能使用 escapeHTML(),由於轉義 " 後,JSON 格式會被破壞。 但安全組又發現有漏洞,原來這樣內聯 JSON 也是不安全的:函數

  • 當 JSON 中包含 U+2028 或 U+2029 這兩個字符時,不能做爲 JavaScript 的字面量使用,不然會拋出語法錯誤。
  • 當 JSON 中包含字符串 時,當前的 script 標籤將會被閉合,後面的字符串內容瀏覽器會按照 HTML 進行解析;經過增長下一個 <script> 標籤等方法就能夠完成注入。

因而咱們又要實現一個 escapeEmbedJSON() 函數,對內聯 JSON 進行轉義。 轉義規則以下:ui

修復後的代碼以下:url

<script>
var initData = <%= escapeEmbedJSON(data.toJSON()) %>
複製代碼
  • HTML 轉義是很是複雜的,在不一樣的狀況下要採用不一樣的轉義規則。若是採用了錯誤的轉義規則,頗有可能會埋下 XSS 隱患。
  • 應當儘可能避免本身寫轉義庫,而應當採用成熟的、業界通用的轉義庫。

總結

  • 在 HTML 中內嵌的文本中,惡意內容以 script 標籤造成注入。
  • 在內聯的 JavaScript中,拼接的數據突破了本來的限制(字符串,變量,方法名等)。
  • 在標籤屬性中,惡意內容包含引號,從而突破屬性值的限制,注入其餘屬性或者標籤。
  • 在標籤的 href、src 等屬性中,包含 javascript: 等可執行代碼。
  • 在 onload、onerror、onclick 等事件中,注入不受控制代碼。
  • 在 style 屬性和標籤中,包含相似 background-image:url("javascript:..."); 的代碼(新版本瀏覽器已經能夠防範)。
  • 在 style 屬性和標籤中,包含相似 expression(...) 的 CSS 表達式代碼(新版本瀏覽器已經能夠防範)。

總之,若是開發者沒有將用戶輸入的文本進行合適的過濾,就貿然插入到 HTML 中,這很容易形成注入漏洞。攻擊者能夠利用漏洞,構造出惡意的代碼指令,進而利用惡意代碼危害數據安全。

插入 JSON 的地方不能使用 escapeHTML(),由於轉義 " 後,JSON 格式會被破壞。 但安全組又發現有漏洞,原來這樣內聯 JSON 也是不安全的:

當 JSON 中包含 U+2028 或 U+2029 這兩個字符時,不能做爲 JavaScript 的字面量使用,不然會拋出語法錯誤。 當 JSON 中包含字符串 時,當前的 script 標籤將會被閉合,後面的字符串內容瀏覽器會按照 HTML 進行解析;經過增長下一個

相關文章
相關標籤/搜索