DOM-XSS攻擊原理與防禦

来源:https://www.cnblogs.com/mysticbinary/archive/2020/03/22/12542695.html
-Advertisement-
Play Games

XSS的中文名稱叫跨站腳本,是WEB漏洞中比較常見的一種,特點就是可以將惡意HTML/JavaScript代碼註入到受害用戶瀏覽的網頁上,從而達到劫持用戶會話的目的。XSS根據惡意腳本的傳遞方式可以分為3種,分別為反射型、存儲型、DOM型,前面兩種惡意腳本都會經過伺服器端然後返回給客戶端,相對DOM ...


XSS的中文名稱叫跨站腳本,是WEB漏洞中比較常見的一種,特點就是可以將惡意HTML/JavaScript代碼註入到受害用戶瀏覽的網頁上,從而達到劫持用戶會話的目的。XSS根據惡意腳本的傳遞方式可以分為3種,分別為反射型、存儲型、DOM型,前面兩種惡意腳本都會經過伺服器端然後返回給客戶端,相對DOM型來說比較好檢測與防禦,而DOM型不用將惡意腳本傳輸到伺服器在返回客戶端,這就是DOM型和反射、存儲型的區別,所以我這裡就單獨的談一下DOM型XSS。

DOM文檔

為了更好的理解DOM型XSS,先瞭解一下DOM,畢竟DOM型XSS就是基於DOM文檔對象模型的。對於瀏覽器來說,DOM文檔就是一份XML文檔,當有了這個標準的技術之後,通過JavaScript就可以輕鬆的訪問它們了。

下麵舉例一個DOM將HTML代碼轉化成樹狀結構:

<html>
    <head>
        <meta charset="gbk" />
        <title> TEST </title>
    </head>
    <body>
        <p>The is p.<p>
        <h1>Product:</h1>
        <ul>
            <li>Apple</li>
            <li>Pear</li>
            <li>Corn</li>
        </ul>
    </body>
</html>

轉化成模型如下圖:

這樣做的好處就是,通過這種簡單的樹狀結構,就能把元素之間的關係簡單明晰的表示出來,方便客戶端的JavaScript腳本通過DOM動態的檢查和修改頁面內容,不依賴服務端的數據。

利用原理

客戶端JavaScript可以訪問瀏覽器的DOM文本對象模型是利用的前提,當確認客戶端代碼中有DOM型XSS漏洞時,並且能誘使(釣魚)一名用戶訪問自己構造的URL,就說明可以在受害者的客戶端註入惡意腳本。利用步驟和反射型很類似,但是唯一的區別就是,構造的URL參數不用發送到伺服器端,可以達到繞過WAF、躲避服務端的檢測效果。

為了更方便大家的理解,下麵我舉幾個場景給大家理解。

場景一:innerHTML

<html>
    <head>
        <title> DOM-XSS TEST </title>
        <style>
            #box{width:250px;height:200px;border:1px solid #e5e5e5;background:#f1f1f1;}
        </style>
    </head>
    <body>
        <script>
            window.onload= function(){
                var oBox=document.getElementById("box");
                var oSpan=document.getElementById("span1");
                var oText=document.getElementById("text1");
                var oBtn=document.getElementById("Btn");
                oBtn.onclick = function(){
                    oBox.innerHTML = oBox.innerHTML + oSpan.innerHTML + oText.value + "<br/>";
                    // oBox.innerHTML += oSpan.innerHTML + oText.value +  "<br/>";//這是簡便的寫法,在js中 a=a+b ,那麼也等同於 a+=b
                    oText.value=""
                };
            }
        </script>

        <div id="box"></div>
        <span id="span1">小明:</span>
        <input type="text" id="text1"/>
        <input id="Btn" type="button" value="發送消息" name=""/>
    </body>
</html>

第一次是正常訪問:
hellow

第二次是將JavaScript代碼作為參數寫入值中:
<svg/onload=alert(1)>

這裡我只在火狐瀏覽器利用成功,在chrome利用失敗,我猜可能chrome對安全防護做得比較好,這裡不繼續各個瀏覽器版本問題。

使用innerHTML、outerHTML 時要註意,標簽需不進行編碼處理,可能會導致XSS。防護方法就是替換成innerText,它自動將HTML標簽解析為普通文本,所以HTML標簽不會被執行,避免XSS攻擊。

oBox.innerText = oBox.innerHTML + oSpan.innerHTML + oText.value + "<br/>";

場景二:跳轉

<html>
    <head>
        <title> DOM-XSS TEST </title>
    </head>
    <body>
        <script>
            var hash = location.hash;
            if(hash){
                var url = hash.substring(1);
                location.href = url;
            }
        </script>
    </body>
</html>

正常訪問是用#去實現頁面跳轉,但是因為跳轉部分參數可控,可能導致Dom xss。

通過 location.hash 的方式,將參數寫在 # 號後,既能讓JS讀取到該參數,又不讓該參數傳入到伺服器,從而避免了WAF的檢測。
變數hash作為可控部分,並帶入url中,變數hash控制的是#之後的部分,可以使用偽協議#javascript:alert(1)。常見的幾種偽協議有javascript:vbscript:data:等。而現在的移動端(android和ios),都可以自定義這種協議從瀏覽器打開本地app,具體可以看看https://www.cnblogs.com/WuXiaolong/p/8735226.html

#javascript:alert(1)

場景三:eval

#';alert(1);//
直接將用戶輸入數據拼接到代碼里。

eval("var x = '" + location.hash + "'");

場景四:cookie、referrer

從localStorage、SessionStorage、Cookies儲存源中取數據,這些值往往會被開發者忽略,認為這些值都是在瀏覽器獲取的,是安全的,就未進行處理。

var cookies = document.cookie;
document.write(cookies);

場景五:document.write 、document.URL.indexOf("id=")

var ids = document.URL;
document.writeln(ids.substring(ids.indexOf("id=")+3,ids.length));

indexOf獲取url裡面的參數,然後通過writeln( )或者write( )輸出到HTML,造成xss,不過我現在(2020.3)在chrome和firefox瀏覽器測試,write()函數很難利用,除非結合一些特殊場景。

防護策略

還有一些正則匹配缺陷、業務邏輯型缺陷、配合移動端跳轉等、使用第三方前端框架(比如多媒體編輯框)等場景沒有一一進行說明(精力實在有限了...),後期有空可能會繼續補全這些場景。

檢測的流程就是通過查看代碼是否有document.write、eval、window之類能造成危害的地方,然後通過回溯變數和函數的調用過程,查看用戶是否能控制輸入。如果能控制輸入,就看看是否能複習,能複習就說明存在DOM XSS,需要對輸入的數據進行編碼。

代碼審計時審計的特征點(包括但不限於):

            var elements = location.hash;
            elements.indexOf
            
            var oBtn=document.getElementById("Btn");
            oBtn.innerHTML
            oBtn.outerHTML
            
            document.createElement
            oBtn.setAttribute
            oBtn.appendChild

            document.write
            document.writeln
            
            eval("var x = '" + location.hash + "'");
            setTimeout("alert('xss')", 1000)
            window.setTimeout
            document.setTimeout
            window.setInterval

            document.execCommand('ForeColor',false,'#BBDDCC'); 
            document.createElement
            document.createElementNS
            document.createEvent
            document.createXxx

js語法很靈活、庫函數也很多,這裡沒法完全列舉全,我覺得需要對js語法體系有一定瞭解,才可能更多的找全這些特征。

當業務需要必須得將用戶輸入的數據放入html,那就要儘量使用安全的方法,比如innerText(),testContent()等。在使用框架時儘量使用框架自帶的安全函數。

參考文檔

《XSS跨站腳本-攻擊剖析與防禦》
《Web漏洞防護》
https://xz.aliyun.com/t/5181
https://domgo.at/cxss/example
https://www.secpulse.com/archives/92286.html


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 很多的小伙伴,經常會有這樣的困惑,我看了很多技術的學習文檔、書籍、甚至視頻,我想動手實踐,於是我打開了GitHub,想找個開源項目,進行學習,獲取項目實戰經驗。這個時候很多小伙伴就會面臨這樣的問題:“我不會搜啊,我該怎麼找呀?”,最終只能放棄。相信看完這篇文章,你就可以學會如何精準地在GitHub搜 ...
  • 慕課網-2019年android工程師 攻城獅 鏈接:https://pan.baidu.com/s/1HgKR7dPbZrJbm4LUEMG6rQ 提取碼:ge2a 複製這段內容後打開百度網盤手機App,操作更方便哦 微雲: 鏈接:https://share.weiyun.com/5PsCNB9 ...
  • 靈感來源於前端CSS畫紅心的原理 "參考" 上代碼 簡單調用如下: ...
  • 效果圖 首先是目錄結構 menu.html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>menu</title> <meta name="viewport" content="width=device-w ...
  • 基於node npm & vue-cli & element UI創建vue單頁應用 開發環境 Win 10 node-v10.15.3-x64.msi 下載地址: https://nodejs.org/en/ 安裝node 安裝vue-cli 1、安裝node-v10.15.3-x64.msi 2 ...
  • 出處:https://www.cnblogs.com/zengyuanjun/p/7429968.html /** * @desc 面向aop編程 * @param {Function} originFunc - 源方法 * @param {Function} before - 在源代碼執行之前的方 ...
  • 冒泡排序和選擇排序 作用和原理 將數組中的數值,按照執行的順序,從小到大排序或者從大到小排序,本文中均為從小到大排序。 冒泡排序 原理: 相鄰的兩個單位,比較存儲的數據,如果第一個單元的數據較大,就將兩個相鄰單元,交換存儲數據 核心: 交換存儲的數據 兩個相鄰的單元,比較數據大小,第一個單元數值較大 ...
  • 大家好,我是逆戰班的一員,今天給大家講解一下Js迴圈中的For迴圈。 For迴圈是JS迴圈中一個非常重要的部分。 我們先講一下for迴圈的作用: For迴圈用在需要重覆執行的某些代碼,比如從1列印到100;或者尋找1到100中的偶數、奇數、質數、合數等等。 然後是For迴圈語句的基本結構: for( ...
一周排行
    -Advertisement-
    Play Games
  • 前言 在我們開發過程中基本上不可或缺的用到一些敏感機密數據,比如SQL伺服器的連接串或者是OAuth2的Secret等,這些敏感數據在代碼中是不太安全的,我們不應該在源代碼中存儲密碼和其他的敏感數據,一種推薦的方式是通過Asp.Net Core的機密管理器。 機密管理器 在 ASP.NET Core ...
  • 新改進提供的Taurus Rpc 功能,可以簡化微服務間的調用,同時可以不用再手動輸出模塊名稱,或調用路徑,包括負載均衡,這一切,由框架實現並提供了。新的Taurus Rpc 功能,將使得服務間的調用,更加輕鬆、簡約、高效。 ...
  • 順序棧的介面程式 目錄順序棧的介面程式頭文件創建順序棧入棧出棧利用棧將10進位轉16進位數驗證 頭文件 #include <stdio.h> #include <stdbool.h> #include <stdlib.h> 創建順序棧 // 指的是順序棧中的元素的數據類型,用戶可以根據需要進行修改 ...
  • 前言 整理這個官方翻譯的系列,原因是網上大部分的 tomcat 版本比較舊,此版本為 v11 最新的版本。 開源項目 從零手寫實現 tomcat minicat 別稱【嗅虎】心有猛虎,輕嗅薔薇。 系列文章 web server apache tomcat11-01-官方文檔入門介紹 web serv ...
  • C總結與剖析:關鍵字篇 -- <<C語言深度解剖>> 目錄C總結與剖析:關鍵字篇 -- <<C語言深度解剖>>程式的本質:二進位文件變數1.變數:記憶體上的某個位置開闢的空間2.變數的初始化3.為什麼要有變數4.局部變數與全局變數5.變數的大小由類型決定6.任何一個變數,記憶體賦值都是從低地址開始往高地 ...
  • 如果讓你來做一個有狀態流式應用的故障恢復,你會如何來做呢? 單機和多機會遇到什麼不同的問題? Flink Checkpoint 是做什麼用的?原理是什麼? ...
  • C++ 多級繼承 多級繼承是一種面向對象編程(OOP)特性,允許一個類從多個基類繼承屬性和方法。它使代碼更易於組織和維護,並促進代碼重用。 多級繼承的語法 在 C++ 中,使用 : 符號來指定繼承關係。多級繼承的語法如下: class DerivedClass : public BaseClass1 ...
  • 前言 什麼是SpringCloud? Spring Cloud 是一系列框架的有序集合,它利用 Spring Boot 的開發便利性簡化了分散式系統的開發,比如服務註冊、服務發現、網關、路由、鏈路追蹤等。Spring Cloud 並不是重覆造輪子,而是將市面上開發得比較好的模塊集成進去,進行封裝,從 ...
  • class_template 類模板和函數模板的定義和使用類似,我們已經進行了介紹。有時,有兩個或多個類,其功能是相同的,僅僅是數據類型不同。類模板用於實現類所需數據的類型參數化 template<class NameType, class AgeType> class Person { publi ...
  • 目錄system v IPC簡介共用記憶體需要用到的函數介面shmget函數--獲取對象IDshmat函數--獲得映射空間shmctl函數--釋放資源共用記憶體實現思路註意 system v IPC簡介 消息隊列、共用記憶體和信號量統稱為system v IPC(進程間通信機制),V是羅馬數字5,是UNI ...