CSRF 攻擊與防禦

admin發表於2019-11-18

由於HTTP協議是無狀態的,Cookie出現之前,網站沒有互動能力。

網站沒有使用者登入等功能,只能夠簡單的從伺服器請求檢視頁面內容。

發明Cookie的最初目的,就是為了維護網站訪問資訊,比如記住使用者名稱和密碼,保持登入狀態。

居心叵測之人利用Cookie應用的一些特點,做一些損人利己的事情,本文介紹一下與Cookie相關的CSRF攻擊。

一.CSRF攻擊概念:

CSRF的全稱是Cross-site request forgery,翻譯成中文是跨站請求偽造。

此攻擊是利用受害者在某一站點的合法身份,進行一些損人利己操作,例如商品購買或轉賬等操作。

二.CSRF攻擊原理:

此攻擊原理非常的簡單,下面分步進行一下介紹。

(1).首先使用者合法登入了某一網站,假定就是螞蟻部落。

(2).合法登入之後,在本地Cookie寫入與登入相關的合法資訊。

(3).每次請求螞蟻部落頁面,都會將在Cookie中儲存的登入資訊隨著HTTP請求傳送到伺服器。

(4).在尚未登出的情況下,訪問一個居心叵測的危險網站,CSRF攻擊的機會就來了。

居心叵測者達成CSRF攻擊的目的,需要滿足如下兩個條件:

(1).使用者登入網站,並將使用者身份驗證的資訊寫入Cookie儲存於客戶端。

(2).在使用者尚未登出的情況下,訪問了一個危險網站。

下面再來闡述一下CSRF攻擊成功的過程:

(1).在未登出的情況下訪問一個危險網站。

(2).然後在這個危險網站通過非同步或者同步方式向螞蟻部落某些連結發起請求。

在危險網站向螞蟻部落發起請求的方式主要有如下幾種:

(1).載入靜態資源,比如載入圖片或者CSS檔案等。

(2).點選超連結。

(3).提交表單。

(4).AJAX請求。下面看一個比較典型的攻擊方式,程式碼如下:

[HTML] 純文字檢視 複製程式碼
<img src="http://www.softwhy.com/give.php?toUserId=5&jinbi=80">

圖片雖然不能正常顯示,但是src值所規定的連結能夠被正常的請求。

且使用者並未登出,所以能夠完成身份合法性驗證,在毫不知情的情況下給使用者ID為5的使用者轉80金幣。

再來演示一下如何採用提交表單方式實現CSRF攻擊,程式碼如下:

[HTML] 純文字檢視 複製程式碼執行程式碼
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="author" content="http://www.softwhy.com/" />
<title>螞蟻部落</title>
<style> 
div{ 
  width:420px; 
  height:420px; 
  background-color:#999; 
  border-radius:180px 40px; 
  margin:0px auto; 
} 
</style> 
<script>
function badAction(){
  let iframe = document.frames["badboy"];
  iframe.document.Submit("myform");
}
</script>
</head> 
<body onload="badAction()">
  <iframe name="badboy" display="none">
    <form method="post" name="myform" action="http://www.softwhy.com/give.php">
      <input type="hidden" name="toUserId" value="5">
     <input type="hidden" name="jinbi" value="80">
    </form>
  </iframe>
</body>
</html>

在惡意網站的頁面中嵌入一個隱藏的iframe。

當這個子視窗載入完畢,就會提交其中對應的表單,同樣會惡意轉走80金幣。

三.CSRF攻擊防禦:

對於CSRF攻擊的防禦非常的簡單,下面進行一下簡單介紹。

CSRF攻擊之所以能夠成功,是因為Cookie中已經儲存了足夠的身份合法性或者操作合法性驗證資訊。

所以我們可以給出攻擊者無法偽造的額外資訊即可有效的防禦CSRF攻擊,下面列舉幾個常見的措施。

1.HTTP Referer請求來源驗證:

在HTTP請求的頭部,具有Referer欄位,它可以記錄當前HTTP請求的來源。

於是,我們可以判斷HTTP請求的來源是否來自於本網站請求,如果不是,那麼拒絕響應。

此方式具有一定的安全隱患:

(1).某些低版本瀏覽器Referer值可以被篡改。

(2).使用者可以自行設定瀏覽器傳送請求時不再提供Referer。

2.新增驗證碼:

這個可以說能夠絕殺CSRF攻擊,因為攻擊者幾乎是不可能提供這個正確的驗證碼。

但是此方式有個很大的缺點,那就是不夠人性化,這一點大家很容易理解。

3.新增一個驗證token:

目的就是增加一個攻擊者無法偽造的額外資訊。

下面簡單闡述一下大致原理,不考慮細節,以表單提交作為例子:

(1).使用者訪問表單頁面的時候,伺服器生成一個隨機token,可以儲存於Cookie或者Session中。

(2).以存入Cookie為例,將這個token寫入隱藏表單元素中,程式碼如下:

[PHP] 純文字檢視 複製程式碼
<?php
  $token = $_COOKIE['token'];
?>
<input type=”hidden” name=”token” value=”<?=$token?>”>

上面以PHP程式碼大致演示了將生成的隨機token寫入隱藏表單元素。

(3).當提交表單的時候,會將這個隱藏元素的value傳送到伺服器,然後與儲存在Cookie中的值進行比對。

(4).由於第三方的網站無法獲取Cookie值,所以攻擊者也就幾乎不可能正確構建token的值。

4.為Cookie設定SameSite屬性:

本文不再具體介紹詞方式,具體參閱Cookie SameSite 屬性一章節。

相關文章