Python自動化營運 - day17 - Django(三)CSRF

來源:互聯網
上載者:User

標籤:alt   開發   存在   form提交   理論   其他   referer   djang   html   

CSRF跨站請求偽造

  CSRF跨網站請求偽造(Cross—Site Request Forgery),跟XSS攻擊一樣,存在巨大的危害性,你可以這樣來理解:攻擊者盜用了你的身份,以你的名義發送惡意請求,對伺服器來說這個請求是完全合法的,但是卻完成了攻擊者所期望的一個操作,比如以你的名義發送郵件、發訊息,盜取你的帳號,添加系統管理員,甚至於購買商品、虛擬貨幣轉賬等。 

CSRF攻擊介紹及防禦

人設:Web A為存在CSRF漏洞的網站,Web B為攻擊者構建的惡意網站,User C為Web A網站的合法使用者。

CSRF攻擊攻擊原理及過程如下:

  1. 使用者C開啟瀏覽器,訪問受信任網站A,輸入使用者名稱和密碼請求登入網站A;

  2.在使用者資訊通過驗證後,網站A產生Cookie資訊並返回給瀏覽器,此時使用者登入網站A成功,可以正常發送請求到網站A;

  3. 使用者未退出網站A之前,在同一瀏覽器中,開啟一個TAB頁訪問網站B;

  4. 網站B接收到使用者請求後,返回一些攻擊性代碼,並發出一個請求要求訪問第三方網站A;

  5. 瀏覽器在接收到這些攻擊性代碼後,根據網站B的請求,在使用者不知情的情況下攜帶Cookie資訊,向網站A發出請求。網站A並不知道該請求其實是由B發起的,所以會根據使用者C的Cookie資訊以C的許可權處理該請求,導致來自網站B的惡意代碼被執行。

PS:還有一種情況是:多視窗瀏覽器,它便捷的同時也帶來了一些問題,因為多視窗瀏覽器新開的視窗是具有當前所有會話的。即我用IE登陸了我的Blog,然後我想看新聞了,又運行一個IE進程,這個時候兩個IE視窗的會話是彼此獨立的,從看新聞的IE發送請求到Blog不會有我登入的cookie;但是多視窗瀏覽器永遠都只有一個進程,各視窗的會話是通用的,即看新聞的視窗發請求到Blog是會帶上我在blog登入的cookie,也有可能產生CSRF攻擊。

        受害者 Bob 在銀行有一筆存款,通過對銀行的網站發送請求 http://bank.example/withdraw?account=bob&amount=1000000&for=bob2 可以使 Bob 把 1000000 的存款轉到 bob2 的帳號下。通常情況下,該請求發送到網站後,伺服器會先驗證該請求是否來自一個合法的 session,並且該 session 的使用者 Bob 已經成功登陸。        駭客 Mallory 自己在該銀行也有賬戶,他知道上文中的 URL 可以把錢進行轉帳操作。Mallory 可以自己發送一個請求給銀行:http://bank.example/withdraw?account=bob&amount=1000000&for=Mallory。但是這個請求來自 Mallory 而非 Bob,他不能通過安全認證,因此該請求不會起作用。        這時,Mallory 想到使用 CSRF 的攻擊方式,他先自己做一個網站,在網站中放入如下代碼: src=”http://bank.example/withdraw?account=bob&amount=1000000&for=Mallory ”,並且通過廣告等誘使 Bob 來訪問他的網站。當 Bob 訪問該網站時,上述 url 就會從 Bob 的瀏覽器發向銀行,而這個請求會附帶 Bob 瀏覽器中的 cookie 一起發向銀行伺服器。大多數情況下,該請求會失敗,因為他要求 Bob 的認證資訊。但是,如果 Bob 當時恰巧剛訪問他的銀行後不久,他的瀏覽器與銀行網站之間的 session 尚未到期,瀏覽器的 cookie 之中含有 Bob 的認證資訊。這時,悲劇發生了,這個 url 請求就會得到響應,錢將從 Bob 的帳號轉移到 Mallory 的帳號,而 Bob 當時毫不知情。等以後 Bob 發現賬戶錢少了,即使他去銀行查詢日誌,他也只能發現確實有一個來自於他本人的合法請求轉移了資金,沒有任何被攻擊的痕迹。而 Mallory 則可以拿到錢後逍遙法外。     
CSRF攻擊執行個體防禦CSRF攻擊

       目前防禦 CSRF 攻擊主要有三種策略:驗證 HTTP Referer 欄位;在請求地址中添加 token 並驗證;在 HTTP 頭中自訂屬性並驗證。

      (1)驗證 HTTP Referer 欄位        根據 HTTP 協議,在 HTTP 頭中有一個欄位叫 Referer,它記錄了該 HTTP 要求的來源地址。在通常情況下,訪問一個安全受限頁面的請求來自於同一個網站,比如需要訪問 http://bank.example/withdraw?account=bob&amount=1000000&for=Mallory,使用者必須先登陸 bank.example,然後通過點擊頁面上的按鈕來觸發轉賬事件。這時,該轉帳請求的 Referer 值就會是轉賬按鈕所在的頁面的 URL,通常是以 bank.example 網域名稱開頭的地址。而如果駭客要對銀行網站實施 CSRF 攻擊,他只能在他自己的網站構造請求,當使用者通過駭客的網站發送請求到銀行時,該請求的 Referer 是指向駭客自己的網站。因此,要防禦 CSRF 攻擊,銀行網站只需要對於每一個轉賬請求驗證其 Referer 值,如果是以 bank.example 開頭的網域名稱,則說明該請求是來自銀行網站自己的請求,是合法的。如果 Referer 是其他網站的話,則有可能是駭客的 CSRF 攻擊,拒絕該請求。        這種方法的顯而易見的好處就是簡單易行,網站的普通開發人員不需要操心 CSRF 的漏洞,只需要在最後給所有安全敏感的請求統一增加一個攔截器來檢查 Referer 的值就可以。特別是對於當前現有的系統,不需要改變當前系統的任何已有代碼和邏輯,沒有風險,非常便捷。        然而,這種方法並非萬無一失。Referer 的值是由瀏覽器提供的,雖然 HTTP 協議上有明確的要求,但是每個瀏覽器對於 Referer 的具體實現可能有差別,並不能保證瀏覽器自身沒有安全性漏洞。使用驗證 Referer 值的方法,就是把安全性都依賴於第三方(即瀏覽器)來保障,從理論上來講,這樣並不安全。事實上,對於某些瀏覽器,比如 IE6 或 FF2,目前已經有一些方法可以篡改 Referer 值。如果 bank.example 網站支援 IE6 瀏覽器,駭客完全可以把使用者瀏覽器的 Referer 值設為以 bank.example 網域名稱開頭的地址,這樣就可以通過驗證,從而進行 CSRF 攻擊。即便是使用最新的瀏覽器,駭客無法篡改 Referer 值,這種方法仍然有問題。因為 Referer 值會記錄下使用者的訪問來源,有些使用者認為這樣會侵犯到他們自己的隱私權,特別是有些組織擔心 Referer 值會把組織內網中的某些資訊泄露到外網中。因此,使用者自己可以設定瀏覽器使其在發送請求時不再提供 Referer。當他們正常訪問銀行網站時,網站會因為請求沒有 Referer 值而認為是 CSRF 攻擊,拒絕合法使用者的訪問。       (2)在請求地址中添加 token 並驗證         CSRF 攻擊之所以能夠成功,是因為駭客可以完全偽造使用者的請求,該請求中所有的使用者驗證資訊都是存在於 cookie 中,因此駭客可以在不知道這些驗證資訊的情況下直接利用使用者自己的 cookie 來通過安全驗證。要抵禦 CSRF,關鍵在於在請求中放入駭客所不能偽造的資訊,並且該資訊不存在於 cookie 之中。可以在 HTTP 要求中以參數的形式加入一個隨機產生的 token,並在伺服器端建立一個攔截器來驗證這個 token,如果請求中沒有 token 或者 token 內容不正確,則認為可能是 CSRF 攻擊而拒絕該請求。        這種方法要比檢查 Referer 要安全一些,token 可以在使用者登陸後產生並放於 session 之中,然後在每次請求時把 token 從 session 中拿出,與請求中的 token 進行比對,但這種方法的痛點在於如何把 token 以參數的形式加入請求。對於 GET 請求,token 將附在請求地址之後,這樣 URL 就變成 http://url?csrftoken=tokenvalue。 而對於 POST 請求來說,要在 form 的最後加上 <input type=”hidden” name=”csrftoken” value=”tokenvalue”/>,這樣就把 token 以參數的形式加入請求了。但是,在一個網站中,可以接受請求的地方非常多,要對於每一個請求都加上 token 是很麻煩的,並且很容易漏掉,通常使用的方法就是在每次頁面載入時,使用 javascript 遍曆整個 dom 樹,對於 dom 中所有的 a 和 form 標籤後加入 token。這樣可以解決大部分的請求,但是對於在頁面載入之後動態產生的 html 代碼,這種方法就沒有作用,還需要程式員在編碼時手動添加 token。         該方法還有一個缺點是難以保證 token 本身的安全。特別是在一些論壇之類支援使用者自己發表內容的網站,駭客可以在上面發布自己個人網站的地址。由於系統也會在這個地址後面加上 token,駭客可以在自己的網站上得到這個 token,並馬上就可以發動 CSRF 攻擊。為了避免這一點,系統可以在添加 token 的時候增加一個判斷,如果這個連結是鏈到自己本站的,就在後面添加 token,如果是通向外網則不加。不過,即使這個 csrftoken 不以參數的形式附加在請求之中,駭客的網站也同樣可以通過 Referer 來得到這個 token 值以發動 CSRF 攻擊。這也是一些使用者喜歡手動關閉瀏覽器 Referer 功能的原因。      (3)在 HTTP 頭中自訂屬性並驗證        這種方法也是使用 token 並進行驗證,和上一種方法不同的是,這裡並不是把 token 以參數的形式置於 HTTP 要求之中,而是把它放到 HTTP 頭中自訂的屬性裡。通過 XMLHttpRequest 這個類,可以一次性給所有該類請求加上 csrftoken 這個 HTTP 頭屬性,並把 token 值放入其中。這樣解決了上種方法在請求中加入 token 的不便,同時,通過 XMLHttpRequest 請求的地址不會被記錄到瀏覽器的地址欄,也不用擔心 token 會透過 Referer 泄露到其他網站中去。        然而這種方法的局限性非常大。XMLHttpRequest 請求通常用於 Ajax 方法中對於頁面局部的非同步重新整理,並非所有的請求都適合用這個類來發起,而且通過該類請求得到的頁面不能被瀏覽器所記錄下,從而進行前進,後退,重新整理,收藏等操作,給使用者帶來不便。另外,對於沒有進行 CSRF 防護的遺留系統來說,要採用這種方法來進行防護,要把所有請求都改為 XMLHttpRequest 請求,這樣幾乎是要重寫整個網站,這代價無疑是不能接受的。
三種策略原理django csrf token

  django中,是通過中介軟體來對CSRF進行驗證的,有關中介軟體的資訊,將在後面的小節中說明。PS:還記得之前在settings.py中注釋掉的 django.middleware.csrf.CsrfViewMiddleware 嗎?,它就是用於檢測CSRF的中介軟體。如果我們render返回頁面時,那麼使用者使用get請求訪問網站時,網站會返回一段隨機的csrf_token,同時也會在cookie中寫一個名為csrftoken的key,這兩個key對應的值是不同的。

  根據這兩種token,我們有兩種方式,傳遞、驗證CSRF token(首先開啟csrf中介軟體,如果之前注釋掉的話)。

  1. form表單提交
  2. ajax提交
form表單提交 

在表單中添加{% csrf_token %} 來渲染服務端返回的csrf_token,它會以hidden的形式在form中產生一個input標籤,在我們利用form提交時會一併攜帶發送給服務端進行驗證,當我們使用ajax代替form的submit進行提交時,可以在data欄位,來擷取form表單中渲染的csrf_token,進行提交,當然,這裡的key的名稱必須為csrfmiddlewaretoken,否則無法識別,從產生的input的name屬性就能看到。

 

ajax提交  

當頁面中沒有form表單(擷取不想使用form手動渲染),那麼還可以使用cookie中的csrftoken進行csrf驗證,由於cookie在請求時是放在要求標頭中的,所以這裡使用ajax的headers來定製要求標頭,注意要求標頭的key必須為(X-CSRFtoken),利用jquery cookie外掛程式,使用$.cookie(‘csrftoken‘)來擷取對應的值即可。 

Python自動化營運 - day17 - Django(三)CSRF

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.