閱讀目錄javascript
一:CSRF是什麼?及它的做用?html
CSRF(Cross-site Request Forgery), 中文名字叫:跨站請求僞造。那麼什麼是跨站請求僞造呢?就是用戶登陸一個正常的網站後,因爲沒有退出該正常網站,cookie信息還保留,而後用戶去點擊一個危險的網站頁面,那麼這個時候危險網站就能夠拿到你以前登陸的cookie信息。而後使用cookie信息去作一些其餘事情。java
所以須要完成一次CSRF攻擊,須要完成以下事情:node
1. 登陸受信任的網站A,而且在本地生成cookie。
2. 在不登出網站A的狀況下,繼續訪問危險網站B。git
所以CSRF基本原理是:假設A網站是一個銀行網站,而我是該網站的用戶,當我以受信任的身份登陸了該網站的時候,這時候A網站是經過cookie保留了咱們的登陸狀態,這個時候我去登陸了惡意網站B的時候,B網站就會拿到我登陸A網站的cookie信息到,所以B網站就把拿到的cookie信息去從新請求A網站的接口,可是在該接口後面的參數作一些修改,所以就這樣達到攻擊的目的。github
二:CSRF 如何實現攻擊web
demo(get請求)舉例:安全
假如A網站,它轉帳接口假如是get請求來完成轉帳操做的話,好比我本地的demo查詢接口就當作轉帳接口來打比方吧。(http://localhost:6789/user/query2?name=&age=&sex=). 我這邊的demo舉例仍是以前的實現用戶登陸查詢數據那個demo來打比方哦(http://www.javashuo.com/article/p-rfgwwjrd-by.html).服務器
A網站查詢接口是 http://localhost:6789/user/query2?name=&age=&sex= 這樣的,而後當我查詢(或叫轉帳)完成後或登陸完成後,我該網站並無退出,而是繼續作其餘的事情,好比說切換到其餘頁面去,發現其餘頁面有個A片網站,我發現挺有興趣的,
忽然點擊進去,而後那個A片網站站點正好監聽了銀行轉帳的接口,它把該接口方法一個A網站頁面上去,而後以img標籤的形式去請求下該接口。以下圖所示微信
好比上面的 查看好看的妹子的代碼以下:
<div> <a href="http://localhost:3001/" target="_blank">查看好看的妹子</a> </div>
它會連接到我B站點上的一個服務器下,該B站點的頁面有以下代碼:
<!DOCTYPE html> <html> <head> <meta charset=utf-8> <title>csrf攻擊</title> </head> <body> <div> <img src="http://localhost:6789/user/query2?name=&age=&sex=" style="display:none" /> </div> </body> </html>
那麼只要點擊進來後,那麼就會請求下這個查詢接口(假如這個查詢接口是轉帳的接口的話),那麼攻擊者就會改下下get請求的參數,好比轉帳給某某後,好比轉帳10萬給name=kongzhi, 那麼kongzhi帳戶上就新增了10萬元了,可是登陸用戶的帳戶就減小了10萬了。
出現如上緣由的是:使用get請求是不安全的操做,使用get請求去轉帳,在訪問網站B站點時候,因爲咱們已經登陸了A銀行網站,而在B站點中則是以 img標籤的get方式去請求第三方資源(也就是A網站中的轉帳接口)。所以B站點中的img中接口也會帶上我網站A的cookie去請求數據,可是銀行是根據cookie信息來進行判斷的,只要cookie信息正確,銀行就會把他們當作合法的請求,所以這樣就會被攻擊者利用了。
如上的demo,我使用node啓動了2個服務,一個是 http://localhost:6789 服務,另一個是 http://localhost:3001/ 服務來進行演示下。
demo(post請求)舉例:
因爲get請求不安全,所以銀行網站決定使用post來請求接口,好比我如今查詢接口改爲post了,以下所示:
可是B站點(攻擊者的服務器)也與時俱進,也使用post請求接口,它使用的是隱藏iframe + form表單進行模擬post請求,好比B 站點的提交post請求的頁面代碼改爲以下:
<!DOCTYPE html> <html> <head> <meta charset=utf-8> <meta name="referrer" content="never"> <title>csrf攻擊</title> </head> <body> <div> <form method="post" action="http://localhost:6789/user/query" target="localwindow" id="formId"> <input type="hidden" name="name" value="11"/> <input type="hidden" name="age" value="30" /> <input type="hidden" name="sex" value="1" /> </form> <iframe style="display:none;" name="localwindow"></iframe> </div> <script type="text/javascript"> var f = document.getElementById('formId'); f.submit(); </script> </body> </html>
而後當咱們點擊危險連接的時候,也會發出成功請求,轉帳也能順利進行。以下圖所示:
如上演示也能夠看到,攻擊者也可使用csrf攻擊成功。那麼上面最主要的是演示 get/post 請求對於web安全性的內容,出現這樣的狀況,咱們該如何防範呢?
三:CSRF 防範措施
那麼防範確定是在服務器端那邊防範比較好,具體防範有以下幾種:
1. 驗證 HTTP Referer字段
HTTP協議中有一個訪問來源的字段是Referer. 服務器端能夠根據該字段進行判斷,判斷該來源的域名是不是本地網站,若是不是的話,能夠直接認爲是危險連接。拒絕訪問。可是該方法仍是有缺陷的,好比我把我網站頁面使用微信分享出去,而後其餘人從微信朋友圈點擊進來,那麼該referer也不是本地域名網站的。
2. 加驗證碼
驗證碼雖然能夠保證安全,可是驗證碼須要與用戶交互,感受交互上比較麻煩點。可是因爲用戶體驗的話,網站不可能給接口都加上驗證碼,可是能夠對用戶登陸加上的,好比咱們的博客園登陸的時候有時候須要驗證碼。驗證碼能夠做爲一種手段,可是不是最好的方法。
3. 使用Token
咱們常見的登陸頁面,都是使用token來完成,能夠確保安全性。想要了解 JSON Web Token, 能夠看我以前一篇文章.
好比:用戶登陸頁面,登陸成功後,服務器端會生成一個token,放在用戶的session或cookie當中,之後每次客戶端與服務器端交互的時候都會把該token帶過去,服務器端獲取該token與本身服務器端保存的token對比,若是相同的話,說明是安全的,不然的話,會拒絕該請求的。