標籤:

CSRF防禦,token保存在伺服器session中,客戶端是如何獲取token?

CSRF防禦,客戶端第一次訪問的時候生成token保存在session中,在這次session的有效時間之內,客戶端每次請求都發送token到伺服器,伺服器驗證token是否相同,相同則放行,否則返回錯誤信息,但是我想知道客戶端是怎麼獲取到token然後發送到伺服器的,如果是進入頁面的時候請求伺服器得到的,那麼偽造的請求不一樣可以先請求這個token,獲取這個token之後再在自己偽造的請求上加上token從而偽造請求嗎?


很久沒有再看這個回答了,這裡重新排個版:

——————

關於Session

PHP中Session的數據不是儲存在客戶端上的,而是儲存在伺服器上的;而客戶端使用Cookie儲存一個伺服器分配的客戶端會話序號(Session ID),當客戶端請求伺服器時,會將這個Session ID傳遞給伺服器,伺服器通過配對獲取Session內容。

關於Token

如果你因為各種原因不能使用Session來實現登錄態的話,你可以考慮一下Token。

如果說這個Token是指的用戶登錄的憑據,並用以維持登錄狀態的話,也就是說一個用戶必須要輸入用戶名密碼並驗證通過後,伺服器才會分配一個Token,傳回並儲存在客戶端作為憑證(同時儲存在伺服器上)。因此並不是每個人都可以獲得這個Token,只有能提供正確用戶密碼的客戶端才可以。

之後每一次操作,都需要客戶端向伺服器提供這個Token,以驗證登錄狀態,如果考慮安全性的話,還可以增加對User-Agent、IP等信息的驗證。

關於CSRF攻擊和防禦

至於CSRF防禦的話,需要說明一下CSRF的原理:如果你在同一個瀏覽器中同時打開詐騙網站A和網上銀行B,這是,如果網站A中偽造了指向網銀B的連接(或轉賬的表單),而當前瀏覽器中又儲存了B的Token(或Session ID),則詐騙網站A的表單就能被成功提交並執行,然後,然後你的存款就不見了。

但是,網站A本身無法獲取你該用戶的Token的具體值,因此Token是相對安全的。

而為了防範CSRF需要做的是不要將HTTP(S)請求的參數放在GET中,而應該放在POST/PUT/DELETE中通過表單提交,然後在表單中加上再一個變化的Random Key(每次刷新頁面後都會改變,並在伺服器中存儲),請求伺服器時都驗證這個Random Key,就可以防止跨站請求偽造了。


Token被用戶端放在Cookie中(不設置HttpOnly),同源頁面每次發請求都在請求頭或者參數中加入Cookie中讀取的Token來完成驗證。CSRF只能通過瀏覽器自己帶上Cookie,不能操作Cookie來獲取到Token並加到http請求的參數中。

所以CSRF本質原因是「重要操作的所有參數都是可以被攻擊者猜測到的」,Token加密後通過Cookie儲存,只有同源頁面可以讀取,把Token作為重要操作的參數,CSRF無法獲取Token放在參數中,也無法仿造出正確的Token,就被防止掉了


Token同時存放在表單和Session中,在提交請求時,驗證表單中的Token。

Token現在作為防禦CSRF的方法,它是基於「不可預測原則」的,足夠的隨機型。 Token可以放在用戶的Session和Cookie中。

如果望著存在XSS漏洞或是其他的跨域漏洞(如Token出現在URL中),Token會被第三方知曉。


通過正常訪問的頁面里會有,伴隨表單提交到伺服器端。攻擊者無法猜測到token進而構造非法請求


可以的,只要能找到校驗欄位就好了


其中有一點需要注意,攻擊者在攻擊過程中永遠是「瞎」的。他不能得到伺服器端的應答結果。每次只是「盲目」地去試探。所以說他不能先請求然後再利用token。


Forgery Request裡面沒有hidden token這一項,即使寫進去,也很難猜到。而正常的client端,在發送request的時候會包含這一項,和伺服器端對上號,就起到了驗證的作用。


推薦閱讀:

TAG:CSRF |