csrf攻擊的原理和過程
CSRF利用用戶正常登錄產生的cookie,在用戶還在保持登錄狀態時,訪問了釣魚網站傳給用戶發送一張有內容的表單和含有攻擊性的代碼,前端利用js是可以發送請求的,並挾持了用戶的正常網站登錄的cookies訪問正常網站,達到將偽造的表單通過用戶之手傳到網站上的目的。為了避免用戶提交其他網站生成的表單,網站在用戶登錄時簽發給用戶一個csrftoken,該token不存放在cookie中(存放在瀏覽器的local storage中),由網站前端js調用(識別{{csrftoken}}
),在提交表單時需要攜帶該token從而驗證該表單來自於本網站(服務器端的token驗證數據存放在session中)。
怎樣防御CSRF
-
提交驗證碼
在表單中添加一個隨機的數字或字母驗證碼。通過強制用戶和應用進行交互。來有效地遏制CSRF攻擊。 -
Referer Check
檢查假設是非正常頁面過來的請求,則極有可能是CSRF攻擊。 - token驗證
- 在 HTTP 請求中以參數的形式添加一個隨機產生的 token,並在服務器端建立一個攔截器來驗證這個 token,假設請求中沒有token 或者 token 內容不對,則覺得可能是 CSRF 攻擊而拒絕該請求。
- token須要足夠隨機
- 敏感的操作應該使用POST。而不是GET,以form表單的形式提交。能夠避免token泄露。
-
在 HTTP 頭中自己定義屬性並驗證
這樣的方法也是使用 token 並進行驗證。這里並非把 token 以參數的形式置於 HTTP 請求之中,而是把它放到HTTP 頭中自己定義的屬性里。通過 XMLHttpRequest 這個類,能夠一次性給全部該類請求加上 csrftoken 這 HTTP 頭屬性。並把 token 值放入當中。這樣攻克了上種方法在請求中添加 token 的不便。同一時候,通過XMLHttpRequest 請求的地址不會被記錄到瀏覽器的地址欄,也不用操心 token 會透過 Referer 泄露到其它站點中去。
關於token#
- Token 應該被保存起來(放到 local / session stograge)
- Token 除了像 cookie 一樣有有效期,還需要能夠有很多其它的操作方法。一旦 token 過期,僅僅需要又一次獲取一個。你能夠使用一個接口去刷新 token。你甚至能夠把 token 原來的公布時間也保存起來。而且強制在兩星期后又一次登錄什么的。假設你須要撤回 tokens(當 token 的生存期比較長的時候這非常有必要)那么你須要一個 token 的生成管理器去作檢查。
- Local / session storage 不會跨域工作,請使用一個標記 cookie:基於瀏覽器的同源策略
- 有須要的話,要加密而且簽名 token
- 將 JSON Web Tokens 應用到 OAuth 2
關於跨域請求白名單
django-cors擴展 django flask 或者其他擴展
- 編寫中間件,在中間件中攔截處理options
- 判斷請求方式是否是options,如果不是opitons,不做處理,進入視圖執行,否則,按照下面的流程處理
- 從options請求中取出訪問域名,與白名單中的允許域名對比,
- 如果在白名單中,則返回允許跨域訪問,否則返回不允許
瀏覽器的同源策略
同源策略(Same origin policy)是一種約定,它是瀏覽器最核心也最基本的安全功能,如果缺少了同源策略,則瀏覽器的正常功能可能都會受到影響。可以說Web是構建在同源策略基礎之上的,瀏覽器只是針對同源策略的一種實現。說簡單點,同源策略就是瀏覽器本身的一種特殊屬性,瀏覽器在訪問資源時會在同源策略約束下,避免不同的站點相互之間輕易的獲取信息。
所謂同源是指,域名,協議,端口相同。當一個瀏覽器的兩個tab頁中分別打開百度和谷歌的頁面。瀏覽器的百度tab頁執行腳本的時候會檢查這個腳本是屬於哪個頁面的,即檢查是否同源,只有和百度同源的腳本才會被執行。 如果非同源,那么在請求數據時,瀏覽器會在控制台中報一個異常,提示拒絕訪問。
我們知道,瀏覽器是以HTTP請求模式獲取請求資源,如:Http://www.baidu.com:8080/xxxx。 其中HTTP是請求協議,www.baidu.com 是域名,8080是端口號,請求的意思是 使用HTTP協議模式,從域名為 www.baidu.com 的服務器上8080端口部署的服務下請求資源XXXX。
那么當協議,域名,端口不相同時,即為不同源。
現在有一個網站:http://www.a.com/a。 https://www.a.com/a :不同源,協議不同,此處協議是https! http://www.b.com/a :不同源,域名不同 http://www.a.com:8080/a :不同源,端口不同 http://www.a.com/b :同源 綜上,跨域就是請求路徑的url不同源。
可參考文檔:https://developer.mozilla.org/zh-CN/docs/Web/Security/Same-origin_policy
session,localStorage,sessionStorage, cookies存儲機制的區別#
localStorage、sessionStorage、cookies都可以用來在瀏覽器進行數據的緩存存儲。
sessionStorage、cookies這兩個存儲隨着關閉瀏覽器或者停止對服務器的訪問而會消失,並不會永久的存在。
localStorage不會通過這種方式清除,只有當用戶手動清除瀏覽器緩存才能真正的清除掉數據。
session不是用來存儲在客戶端,而是存儲在服務器端。cookies中會保存一個sessionID,以便用戶的身份驗證。
在以前,這些緩存存儲都是由 cookies 完成的。但是cookies不適合大數據量的存儲,它們由每個對服務器的請求來傳遞,這使得 cookie 速度很慢而且效率也不高。
在 HTML5 中,數據不是由每個服務器請求傳遞的,而是只有在請求時使用數據。它使在不影響網站性能的情況下存儲大量數據成為可能。對於不同的網站,數據存儲於不同的區域,並且一個網站只能訪問其自身的數據。
即當瀏覽器打開的tab滿足同源策略后,可以在各頁面之間進行數據的相互存取操作,這樣就可以不用反復進行重復的數據請求操作,如登錄權限,獲取用戶信息等等。