本頁使用了標題或全文手工轉換

跨站請求偽造

維基百科,自由的百科全書
跳至導覽 跳至搜尋

跨站請求偽造(英語:Cross-site request forgery),也被稱為 one-click attack 或者 session riding,通常縮寫為 CSRF 或者 XSRF, 是一種挾制使用者在當前已登入的Web應用程式上執行非本意的操作的攻擊方法。[1]跨網站指令碼(XSS)相比,XSS 利用的是使用者對指定網站的信任,CSRF 利用的是網站對使用者網頁瀏覽器的信任。

攻擊的細節[編輯]

跨站請求攻擊,簡單地說,是攻擊者通過一些技術手段欺騙使用者的瀏覽器去存取一個自己曾經認證過的網站並執行一些操作(如發郵件,發訊息,甚至財產操作如轉帳和購買商品)。由於瀏覽器曾經認證過,所以被存取的網站會認為是真正的使用者操作而去執行。這利用了web中使用者身分驗證的一個漏洞:簡單的身分驗證只能保證請求是發自某個使用者的瀏覽器,卻不能保證請求本身是使用者自願發出的

例子[編輯]

假如一家銀行用以執行轉帳操作的URL位址如下: https://bank.example.com/withdraw?account=AccoutName&amount=1000&for=PayeeName

那麼,一個惡意攻擊者可以在另一個網站上放置如下代碼: <img src="https://bank.example.com/withdraw?account=Alice&amount=1000&for=Badman" />

如果有帳戶名為Alice的使用者存取了惡意站點,而她之前剛存取過銀行不久,登錄資訊尚未過期,那麼她就會損失1000資金。

這種惡意的網址可以有很多種形式,藏身於網頁中的許多地方。此外,攻擊者也不需要控制放置惡意網址的網站。例如他可以將這種位址藏在論壇,部落格等任何使用者生成內容的網站中。這意味著如果伺服器端沒有合適的防禦措施的話,使用者即使存取熟悉的可信網站也有受攻擊的危險

透過例子能夠看出,攻擊者並不能通過CSRF攻擊來直接獲取使用者的帳戶控制權,也不能直接竊取使用者的任何資訊。他們能做到的,是欺騙使用者的瀏覽器,讓其以使用者的名義執行操作

防禦措施[編輯]

權杖同步模式[編輯]

權杖同步模式(英語:Synchronizer token pattern,簡稱STP)。原理是:當使用者傳送請求時,伺服器端應用將權杖(英語:token,一個保密且唯一的值)嵌入HTML表格,並行送給客戶端。客戶端提交HTML表格時候,會將權杖傳送到伺服器端,權杖的驗證是由伺服器端實行的。權杖可以通過任何方式生成,只要確保隨機性和唯一性(如:使用隨機種子【英語:random seed】的雜湊鏈 )。這樣確保攻擊者傳送請求時候,由於沒有該權杖而無法通過驗證。

Django框架預設帶有STP功能:[2]

<form method="post">
    {% csrf_token %}
</form>

彩現後的效果如下:

<form method="post">
    <input type="hidden" name="csrfmiddlewaretoken" value="KbyUmhTLMpYj7CD2di7JKP1P3qmLlkPt" />
</form>

STP能在HTML下運作順利,但會導致伺服器端的複雜度升高,複雜度源於權杖的生成和驗證。因為權杖是唯一且隨機,如果每個表格都使用一個唯一的權杖,那麼當頁面過多時,伺服器由於生產權杖而導致的負擔也會增加。而使用對談(英語:session)等級的權杖代替的話,伺服器的負擔將沒有那麼重。

檢查Referer欄位[編輯]

HTTP頭中有一個Referer欄位,這個欄位用以標明請求來源於哪個位址。在處理敏感數據請求時,通常來說,Referer欄位應和請求的位址位於同一域名下。以上文銀行操作為例,Referer欄位位址通常應該是轉帳按鈕所在的網頁位址,應該也位於bank.example.com之下。而如果是CSRF攻擊傳來的請求,Referer欄位會是包含惡意網址的位址,不會位於bank.example.com之下,這時候伺服器就能識別出惡意的存取。

這種辦法簡單易行,工作量低,僅需要在關鍵存取處增加一步校驗。但這種辦法也有其局限性,因其完全依賴瀏覽器發送正確的Referer欄位。雖然http協定對此欄位的內容有明確的規定,但並無法保證來訪的瀏覽器的具體實現,亦無法保證瀏覽器沒有安全漏洞影響到此欄位。並且也存在攻擊者攻擊某些瀏覽器,篡改其Referer欄位的可能。

添加校驗token[編輯]

由於CSRF的本質在於攻擊者欺騙使用者去存取自己設定的位址,所以如果要求在存取敏感數據請求時,要求使用者瀏覽器提供不儲存在cookie中,並且攻擊者無法偽造的數據作為校驗,那麼攻擊者就無法再執行CSRF攻擊。這種數據通常是表單中的一個數據項。伺服器將其生成並附加在表單中,其內容是一個偽亂數。當客戶端通過表單提交請求時,這個偽亂數也一並提交上去以供校驗。正常的存取時,客戶端瀏覽器能夠正確得到並傳回這個偽亂數,而通過CSRF傳來的欺騙性攻擊中,攻擊者無從事先得知這個偽亂數的值,伺服器端就會因為校驗token的值為空或者錯誤,拒絕這個可疑請求。

參考資料[編輯]

  1. ^ Ristic, Ivan. Apache Security. O'Reilly Media. 2005: 280. ISBN 0-596-00724-8. 
  2. ^ Django documentation | Django. docs.djangoproject.com. [2020-01-21]. (原始內容存檔於2020-01-23).