瞭解什麼是CSRF攻擊及如何鎖定CSRF漏洞

瞭解CSRF攻擊和鎖定CSRF漏洞

網路漏洞很猖獗,而且不斷增加。維護你的使用者的安全和隱私比以往任何時候都更重要。 不解決網路漏洞會導致聲譽毀於一旦,並被監管機構處以鉅額罰款,你還會失去使用者的信任。

網站和網路應用程式很容易受到惡意軟體、垃圾郵件和其他攻擊–本文重點討論其中一個攻擊媒介–跨站請求偽造(CSRF)攻擊。CSRF攻擊特別令人不安,因為它們可以在使用者不知情的情況下發生。開發人員或網站所有者也很難發現它們,因為惡意請求看起來與真實請求高度相似。

本文探討了CSRF攻擊,它是如何工作的,以及你可以採取哪些步驟來準備應對。

  1. 什麼是CSRF攻擊?
  2. CSRF攻擊是如何工作的?
  3. GET請求的CSRF
  4. POST請求的CSRF
  5. 減輕CSRF攻擊的3種方法
  6. 如何使用CSRF令牌防止CSRF攻擊
  7. 如何利用Referrer標頭來防止CSRF攻擊

什麼是CSRF攻擊?

跨站請求偽造攻擊,也被稱為CSRF攻擊,通過提交惡意請求,在不知不覺中欺騙認證使用者,使其執行非預期的操作。

CSRF攻擊是如何工作的

CSRF攻擊是如何工作的。(圖片來源: Okta)

通常情況下,CSRF攻擊涉及改變狀態的請求,因為攻擊者沒有收到迴應。這類請求的例子包括刪除記錄、更改密碼、購買產品或傳送訊息。這些都可以在使用者不知情的情況下發生。

惡意攻擊者通常使用社會工程,通過聊天或電子郵件向毫無戒心的使用者傳送一個連結。

當使用者點選該連結時,它就會執行攻擊者設定的命令。

例如,點選一個連結可以從使用者的賬戶中轉移資金。或者,它可以改變使用者的電子郵件地址,使他們無法重新獲得賬戶訪問權。

CSRF攻擊是如何工作的?

讓使用者在登入時發起一個改變狀態的請求是CSRF攻擊的第一步,也是最關鍵的一步。通過CSRF攻擊,攻擊者的目的是讓已認證的使用者在不知情的情況下向網站或網路應用程式提交一個惡意的網路請求。這些請求可以包括cookies、URL引數和其他在使用者看來正常的資料型別。

要使CSRF攻擊成功,必須發生以下條件:

  • 一個經過驗證的使用者必須登入到一個使用cookies進行會話管理的網路應用程式。
  • 攻擊者必須建立一個改變狀態的偽造請求。
  • 由目標伺服器處理的真正的請求不應包含不可預測的引數。例如,在啟動狀態改變請求之前,請求不應該期望有一個密碼作為驗證的引數。

完成CSRF攻擊的最常見方法是在具有薄弱的SameSite cookie策略的應用程式中使用cookie。 網路瀏覽器自動地、通常是匿名地包括cookies,它們在使用者向某個域發出的任何網路請求中儲存該域所使用的cookies。

SameSite cookie策略定義了瀏覽器在跨站瀏覽情況下如何對待cookie。如果設定為嚴格,cookie就不會在跨網站瀏覽的情況下共享,從而防止CSRF攻擊。如果設定為無,瀏覽器會在所有的跨網站上下文中附加cookie。這就使應用程式容易受到CSRF攻擊。

當使用者在不知情的情況下通過網路瀏覽器提交一個惡意請求時,儲存的cookie會使該請求在伺服器看來是合法的。然後,伺服器通過改變使用者的賬戶、改變會話狀態或返回所請求的資料來響應該請求。

讓我們仔細看看CSRF攻擊途徑的兩個例子,一個是GET請求,另一個是POST請求。

GET請求的CSRF

首先,考慮一個金融銀行網路應用程式使用的GET請求,攻擊利用了GET請求和超連結傳遞。

假設轉賬的GET請求看起來是這樣的:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
GET https://xymbank.com/online/transfer?amount=1000&accountNumber=547895 HTTP/1.1
GET https://xymbank.com/online/transfer?amount=1000&accountNumber=547895 HTTP/1.1
GET https://xymbank.com/online/transfer?amount=1000&accountNumber=547895 HTTP/1.1

在上面的真實請求中,使用者要求將1000美元轉到 547895 的賬戶中,作為購買產品的付款。

雖然這個請求是明確、簡單和實用的,但它使賬戶持有人暴露在CSRF攻擊之下。這是因為該請求不需要攻擊者可能不知道的細節。因此,為了發起攻擊,攻擊者只需要改變這個請求的引數(金額和賬戶號碼),就可以建立一個可執行的偽造請求。

惡意請求對銀行的任何使用者都有效,只要他們正在進行cookie管理會話。

以下是偽造的向黑客賬戶(此處為 654585)轉賬500美元的請求。請注意,下面的示例是CSRF攻擊中涉及的步驟的高度簡化版本,以供解釋。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
GET https://xymbank.com/online/transfer?amount=500&accountNumber=654585 HTTP/1.1
GET https://xymbank.com/online/transfer?amount=500&accountNumber=654585 HTTP/1.1
GET https://xymbank.com/online/transfer?amount=500&accountNumber=654585 HTTP/1.1

一旦完成,攻擊者必須找出一種方法,誘騙使用者在登入線上銀行應用程式時傳送此請求。實現這一點的方法之一是建立一個無害的超連結,以吸引使用者的注意。連結可能如下所示:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<a
href="https://xymbank.com/online/transfer?amount=500&accountNumber=654585">Click here to get more information</a>.
<a href="https://xymbank.com/online/transfer?amount=500&accountNumber=654585">Click here to get more information</a>.
<a
href="https://xymbank.com/online/transfer?amount=500&accountNumber=654585">Click here to get more information</a>.

如果攻擊者找到了目標的正確電子郵件地址,他們可以通過電子郵件將其傳送給許多銀行客戶。那些在登入時單擊連結的人將觸發請求,從登入的帳戶向攻擊者傳送500美元。

POST請求的CSRF

讓我們看看,如果同一個金融機構只接受POST請求,他們會如何經歷CSRF。在這種情況下,在GET請求的例子中使用的超連結傳遞將不起作用。因此,一個成功的CSRF攻擊將需要攻擊者建立一個HTML表單。為購買的產品傳送1000美元的真正請求看起來是這樣的:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
POST /online/transfer HTTP/1.1
Host: xymbank.com
Content-Type: application/x-www-form-urlencoded
Cookie: session=FRyhityeQkAPzeQ5gHgTvlyxHJYhg
amount=1000
account=547895
POST /online/transfer HTTP/1.1 Host: xymbank.com Content-Type: application/x-www-form-urlencoded Cookie: session=FRyhityeQkAPzeQ5gHgTvlyxHJYhg amount=1000 account=547895
POST /online/transfer HTTP/1.1
Host: xymbank.com
Content-Type: application/x-www-form-urlencoded
Cookie: session=FRyhityeQkAPzeQ5gHgTvlyxHJYhg
amount=1000
account=547895

這個POST請求需要一個cookie來確定使用者的身份,他們希望傳送的金額,以及他們希望傳送的賬戶。攻擊者可以改變這個請求來進行CSRF攻擊。

攻擊者只需在一個偽造的請求中新增一個真正的cookie,就可以使伺服器處理傳輸。他們可以通過建立一個看起來無害的超連結,將使用者帶到一個看起來像這樣的觸發網頁。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<html>
<body>
<form action="https://xymbank.com/online/transfer" method="POST">
<input type="hidden" name="amount" value="500"/>
<input type="hidden" name="account" value="654585" />
</form>
<script>
document.forms[0].submit();
</script>
</body>
</html>
<html> <body> <form action="https://xymbank.com/online/transfer" method="POST"> <input type="hidden" name="amount" value="500"/> <input type="hidden" name="account" value="654585" /> </form> <script> document.forms[0].submit(); </script> </body> </html>
<html>
<body>
<form action="https://xymbank.com/online/transfer" method="POST">
<input type="hidden" name="amount" value="500"/>
<input type="hidden" name="account" value="654585" />
</form>
<script>
document.forms[0].submit();
</script>
</body>
</html>

我們已經在上面的表格中設定了金額和賬戶引數。一旦認證的使用者訪問該頁面,瀏覽器在將請求轉發給伺服器之前會新增會話cookie。然後伺服器將500美元轉發到黑客的賬戶。

減少CSRF攻擊的3種方法

有幾種方法可以防止和大大減輕對你的網站或網路應用的潛在CSRF攻擊,包括:

  • 使用CSRF令牌
  • 使用referrer標頭
  • 選擇一個注重安全的託管解決方案

如何使用CSRF令牌防止CSRF攻擊

一個CSRF安全的網站會給每個會話分配一個唯一的令牌,並與伺服器端和客戶端瀏覽器共享它。每當瀏覽器傳送一個敏感請求時,伺服器都希望它包含指定的CSRF令牌。如果它有錯誤的令牌,伺服器會放棄它。為了安全起見,CSRF令牌並不儲存在客戶端瀏覽器的會話cookies中。

CSRF令牌的潛在漏洞

雖然CSRF令牌是一個很好的安全措施,但這種方法並不是防攻擊的。伴隨著CSRF令牌的一些漏洞包括。

  • 繞過驗證 – 一些應用程式如果沒有找到令牌就跳過驗證步驟。如果攻擊者獲得了對包含令牌的程式碼的訪問權,他們可以刪除該令牌併成功執行CSRF攻擊。因此,如果對伺服器的有效請求看起來像這樣。
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
POST /change_password
POST body:
password=pass123&csrf_token=93j9d8eckke20d433
POST /change_password POST body: password=pass123&csrf_token=93j9d8eckke20d433
POST /change_password
POST body:
password=pass123&csrf_token=93j9d8eckke20d433

攻擊者只需要刪除令牌,然後像這樣傳送就可以執行攻擊:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
POST /change_password
POST body:
password=pass123
POST /change_password POST body: password=pass123
POST /change_password
POST body:
password=pass123
  • 池式令牌 – 一些應用程式維護一個令牌池來驗證使用者會話,而不是為一個會話指定一個特定的令牌。攻擊者只需要獲得池中的一個令牌就可以冒充網站的任何使用者。

攻擊者可以使用他們的賬戶登入到一個應用程式,以獲得一個令牌,例如:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
[application_url].com?csrf_token=93j9d8eckke20d433
[application_url].com?csrf_token=93j9d8eckke20d433
[application_url].com?csrf_token=93j9d8eckke20d433

而由於令牌是池化的,攻擊者可以複製並使用該相同的令牌登入到不同的使用者賬戶,因為你會再次使用它:

  • CSRFs可以將令牌複製到cookie中 – 一些應用程式會將與令牌相關的引數複製到使用者的cookie中。如果攻擊者獲得了這樣的cookie,他們可以很容易地建立另一個cookie,把它放在瀏覽器中,並執行CSRF攻擊。

因此,攻擊者可以使用他們的賬戶登入到一個應用程式,並開啟cookie檔案,看到以下內容:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
Csrf_token:93j9d8eckke20d433
Csrf_token:93j9d8eckke20d433
Csrf_token:93j9d8eckke20d433

然後他們可以使用這些資訊建立另一個cookie來完成攻擊

  • 無效的令牌 – 一些應用程式不匹配CSRF令牌到使用者會話。在這種情況下,攻擊者可以真正地登入到一個會話中,獲得與上述類似的CSRF令牌,並使用它來策劃對受害者會話的CSRF攻擊。

如何利用Referer Header防止CSRF攻擊

另一個防止CSRF攻擊的策略是使用referrer標頭。在HTTP中,referrer標頭表示請求的來源。它們通常被用來進行分析、優化和記錄。

你也可以在伺服器端啟用檢查referrer標頭,以防止CSRF攻擊。伺服器端檢查請求的來源,並確定請求的目標來源。如果它們匹配,那麼該請求是允許的。如果不匹配,伺服器會放棄該請求。

使用referrer標頭像比使用令牌要容易得多,因為它不需要單獨的使用者識別。

Referrer標頭的潛在漏洞

與CSRF標記一樣,Referrer標頭資訊也有一些重要的漏洞。

首先,Referrer標標頭檔案不是強制性的,有些網站會在沒有Referrer標標頭檔案的情況下傳送請求。如果CSRF沒有處理沒有標頭資訊的請求的策略,攻擊者可以使用標頭資訊的請求來執行狀態改變的攻擊。

此外,隨著最近引入referrer策略,這種方法變得不再有效。這一規範防止了URL洩露給其他域,使使用者對referrer標頭中的資訊有更多的控制。他們可以選擇暴露部分referrer頭資訊,或者通過在HTML頁面上新增一個後設資料標籤來禁用它,如下所示。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<meta name="referrer" content="no-referrer">
<meta name="referrer" content="no-referrer">
<meta name="referrer" content="no-referrer">

上面的程式碼為這個頁面的所有請求刪除了referrer頭。這樣做使得那些依賴referrer頭的應用程式很難防止來自這樣一個頁面的CSRF攻擊。

小結

跨站請求偽造(CSRF)是一種欺騙認證使用者,使其無意中發起改變狀態的請求的攻擊。它們的目標是那些不能區分有效和偽造的狀態改變請求的應用程式。

CSRF只能在那些依靠會話cookie來識別登入使用者並具有弱的SameSite cookie策略的應用程式上取得成功。他們還需要一個接受不包含未知引數(如密碼)的請求的伺服器。黑客可以使用GET或POST來傳送惡意攻擊。

雖然使用CSRF令牌或強制執行referrer header驗證可以防止一些CSRF攻擊,但這兩種措施都有潛在的漏洞,如果你不小心,就會使你的預防措施失去作用。

評論留言