1. 程式人生 > >js 前端防xss攻擊——百度UEditor解決方案

js 前端防xss攻擊——百度UEditor解決方案

  xss跨站指令碼攻擊(Cross Site Scripting),是一種經常出現在web應用中的電腦保安漏洞,指攻擊者在網頁中嵌入客戶端指令碼(例如JavaScript), 當用戶瀏覽此網頁時,指令碼就會在使用者的瀏覽器上執行,從而達到攻擊者的目的。比如獲取使用者的Cookie,導航到惡意網站,攜帶木馬等。

  大部分的xss漏洞都是由於沒有處理好使用者的輸入,導致攻擊指令碼在瀏覽器中執行,這就是跨站指令碼漏洞的根源。

一、xss攻擊型別

  1.非持久型XSS攻擊

  非持久型XSS(Non-persistent)又叫做反射XSS(Reflect XSS),它是指那些瀏覽器每次都要在引數中提交惡意資料才能觸發的跨站指令碼漏洞。

  非持久型XSS漏洞實際上大多數攻擊資料是包含在URL中的,類似這樣的:http://www.vicitim.com/vul.asp?hi=
[code]。需要使用者的瀏覽器訪問到這個URL惡意程式碼才執行,攻擊者一般會把URL發給使用者讓使用者通過瀏覽器去訪問。不過URL裡面帶有稀奇古怪的程式碼確實有點奇怪,為了掩人耳目,攻擊者可以發一個看起來沒問題的URL,再通過那個頁面跳轉到惡意的URL;甚至也可以讓一個域名轉向到惡意URL,把那個域名發給使用者。

  2.持久型XSS攻擊

  持久型XSS(Persistent)又叫做儲存XSS(Stored XSS),與非持久型XSS相反,它是指通過提交惡意資料到儲存器(比如資料庫、文字檔案等),Web應用程式輸出的時候是從儲存器中讀出惡意資料輸出到頁面的一類跨站指令碼漏洞。

  持久型XSS攻擊就簡單一點,只要第一次把攻擊程式碼提交到伺服器就一勞永逸了。比如我在某個論壇發帖的時候,論壇沒有對傳入的HTML作處理,那麼我就可以發一個帖子內容包含“<script
>
[code]</script>”的帖子。呵呵,然後就守株待兔地等著來看帖子的人執行惡意指令碼了。持久型XSS漏洞是把惡意指令碼儲存到了資料庫,訪問頁面的時候完全沒有預兆,所以它的危害也比非持久型XSS略微高一點。

二、常見的xss攻擊方法

 1.繞過XSS-Filter,利用<>標籤注入Html/JavaScript程式碼;

  2.利用HTML標籤的屬性值進行xss攻擊。例如:<img src=“javascript:alert(‘xss’)”/>;(當然並不是所有的Web瀏覽器都支援Javascript偽協議,所以此類XSS攻擊具有一定的侷限性)

  3. 空格、回車和Tab。如果XSS Filter僅僅將敏感的輸入字元列入黑名單,比如javascript,使用者可以利用空格、回車和Tab鍵來繞過過濾,例如:<img
src=“javas cript:alert(/xss/);”/>
;   4. 利用事件來執行跨站指令碼。例如:<img src=“#” onerror= “alert(1)”/>,當src錯誤的視乎就會執行onerror事件;   5. 利用CSS跨站。例如:Body {backgrund-image: url(“javascript:alert(‘xss’)”)};   6. 擾亂過濾規則。例如:<IMG SRC=“javaSCript: alert(/xss/);”/>;   7.利用字元編碼,透過這種技巧,不僅能讓XSS程式碼繞過服務端的過濾,還能更好地隱藏Shellcode;(JS支援unicode、eacapes、十六進位制、十進位制等編碼形式)   8.拆分跨站法,將xss攻擊的程式碼拆分開來,適用於應用程式沒有過濾 XSS關鍵字元(如<>)卻對輸入字元長度有限制的情況下;   9.DOM型的XSS主要是由客戶端的指令碼通過DOM動態地輸出資料到頁面上,它不依賴於提交資料到伺服器,而是從客戶端獲得DOM中的資料在本地執行。容易導致DOM型的XSS的輸入源包括:Document.URL、Location(.pathname|.href|.search|.hash)、 Document.referrer、Window.name、Document.cookie、localStorage/globalStorage;

三、XSS攻擊防禦

  原則:不相信客戶輸入的資料
  注意: 攻擊程式碼不一定在中

  1.使用XSS Filter。

  輸入過濾,對使用者提交的資料進行有效性驗證,僅接受指定長度範圍內並符合我們期望格式的的內容提交,阻止或者忽略除此外的其他任何資料。比如:電話號碼必須是數字和中劃線組成,而且要設定長度上限。過濾一些些常見的敏感字元,例如:< > ‘ “ & # \ javascript expression  "onclick="  "onfocus";過濾或移除特殊的Html標籤, 例如: <script>, <iframe> ,  &lt; for <, &gt; for >, &quot for;過濾JavaScript 事件的標籤,例如 "onclick=", "onfocus" 等等。

  輸出編碼,當需要將一個字串輸出到Web網頁時,同時又不確定這個字串中是否包括XSS特殊字元(如< > &‘”等),為了確保輸出內容的完整性和正確性,可以使用編碼(HTMLEncode)進行處理。

  2.DOM型的XSS攻擊防禦

  把變數輸出到頁面時要做好相關的編碼轉義工作,如要輸出到 <script>中,可以進行JS編碼;要輸出到HTML內容或屬性,則進行HTML編碼處理。根據不同的語境採用不同的編碼處理方式。

  3.HttpOnly Cookie

  將重要的cookie標記為http only,   這樣的話當瀏覽器向Web伺服器發起請求的時就會帶上cookie欄位,但是在指令碼中卻不能訪問這個cookie,這樣就避免了XSS攻擊利用JavaScript的document.cookie獲取cookie

四、程式碼實現

以下程式碼主要摘自百度UEditor外掛

var xssUtil = {
    /**
     * 將url中的html字元轉義, 僅轉義  ', ", <, > 四個字元
     * @param  { String } str 需要轉義的字串
     * @param  { RegExp } reg 自定義的正則
     * @return { String }     轉義後的字串
     */
    unhtmlForUrl: function (str, reg) {
        return str ? str.replace(reg || /[<">']/g, function (a) {
            return {
                '<': '&lt;',
                '&': '&amp;',
                '"': '&quot;',
                '>': '&gt;',
                "'": '&#39;'
            }[a]

        }) : '';
    },
    /**
     * 將str中的轉義字元還原成html字元
     * @see UE.utils.unhtml(String);
     * @method html
     * @param { String } str 需要逆轉義的字串
     * @return { String } 逆轉義後的字串
     * @example
     * ```javascript
     *
     * var str = '&lt;body&gt;&amp;&lt;/body&gt;';
     *
     * //output: <body>&</body>
     * console.log( UE.utils.html( str ) );
     *
     * ```
     */
    html: function (str) {
        return str ? str.replace(/&((g|l|quo)t|amp|#39|nbsp);/g, function (m) {
            return {
                '&lt;': '<',
                '&amp;': '&',
                '&quot;': '"',
                '&gt;': '>',
                '&#39;': "'",
                '&nbsp;': ' '
            }[m]
        }) : '';
    },
}