CSRF,全稱 Cross Site Request Forgery,跨站請求僞造,是一種欺騙受害用戶在已登陸的web應用上按照攻擊者的指令執行惡意操做的攻擊行爲。攻擊的影響範圍取決於受害用戶所擁有的的權限,由於攻擊者是依賴用戶在當前會話中的鑑權進行惡意操做的。html
CSRF僅在用戶已被受權的狀況下才能生效。經過CSRF,攻擊者能夠繞開web應用的鑑權機制,進而利用受害者的用戶權限對web應用進行惡意操做。好比網上銀行等場景。web
下面是CSRF攻擊的兩個主要組成部分:django
(HTTP session和cookie機制請見cookie與session的區別以及在Django中的實現)api
CSRF攻擊實際上就是利用了HTTP會話的cookie機制,由於瀏覽器會在每次請求中都帶上與web應用關聯的cookie。瀏覽器
假設這是一個合法的url,用於向指定的User用戶轉帳1000塊錢。bash
http://example.com/transfer?amount=1000&account=User
複製代碼
當用戶發送該請求時,若是用戶已經登陸過web應用且鑑權經過,則瀏覽器會在請求中自動攜帶包含鑑權信息的cookie,這樣用戶進行轉帳時就不須要再次進行登陸驗證;若是用戶還未登陸鑑權,則會須要先進行登陸鑑權,而後瀏覽器才能進一步攜帶cookie信息發起轉帳請求。 web應用須要拿到轉帳請求中攜帶的cookie用於驗證用戶信息,才能得知是要從哪一個用戶的帳戶中將錢轉出。cookie
若是web應用能夠接受GET請求,那攻擊者只須要在惡意連接的html中加入以下的代碼,經過img標籤自動向web應用僞造一個轉帳請求。利用瀏覽器自動攜帶cookie的機制,就能夠從用戶帳戶中盜走1000塊錢。session
<img src="http://example.com/transfer?amount=1000&account=Fred" />
複製代碼
該場景中的web應用除了存在CSRF漏洞之外,還有一個問題:任何的GET請求都應該是「只讀「的,不該該對數據產生任何影響。因此該場景中的web應用設計是不合理的。post
下面是使用POST進行攻擊的html表單代碼網站
<h1>You Are a Winner!</h1>
<form action="http://example.com/api/account" method="post">
<input type="hidden" name="Transaction" value="withdraw" />
<input type="hidden" name="Amount" value="1000" />
<input type="submit" value="Click Me"/>
</form>
複製代碼
試想以下攻擊場景:
值得注意的是,SSL是沒法防禦CSRF攻擊的。由於攻擊者只須要在僞造請求中指定https訪問便可。
最經常使用的CSRF防範機制就是使用csrf token機制。
注意,在POST表單中使用csrf token時,要確保表單是提交給本身的web應用的,而不是提交給外部的應用。好比在表單action中指定提交到baidu或者其餘網站,別人是沒法識別請求中的csrf token的,而且同時也存在泄漏csrf token的風險。
cookie由於其自動在請求中攜帶的特色,很容易受到CSRF攻擊。攻擊者不須要獲取用戶的cookie,也能夠直接利用用戶的cookie進行惡意操做。CSRF攻擊的影響取決於用戶所擁有的權限。
因此咱們在web應用設計中要注意,一方面是要嚴格遵照HTTP規範,GET請求必定是」只讀「的,避免接收GET請求進行狀態變動(如數據修改等);另外一方面是對於全部設計狀態變動的請求,如POST、PUT、DELETE等,都須要進行csrf token校驗。
【本文參考】