Skip to content
On this page

CSRF 跨站偽造請求

CSRF (Cross-site request forgery) 跨站偽造請求,駭客 利用使用者在 A 網 已驗証的身份,在使用者進入 第三網 (駭客架設) 時,發起對 A 網 隱藏式的請求指令 達成指定目的,而非透過 使用者 的意願。 creativegroundtech

圖片出處:creativegroundtech

  1. 登入 銀行網
  2. (成功) 取得使用者認證資料
  3. 駭客發送 釣魚網站惡意連結 給使用者
  4. 使用者到 駭客網站 不知情下,送出了到 銀行網 的指令請求
  5. 銀行依 2 取得的身份驗証,成功執行請求。

瀏覽器機制

當發出 請求 給某個網域,其網域關聯的 cookie 也會一起被帶上 請求 之中,所以駭客就是利用 cookie中已驗證的身份,發動攻擊。

攻擊方式

GET

假設後台的 刪除 功能,可以直接以 /delete?id=3 來刪除 id=3的項目。理論上,使用者必須先驗證過個人資料,且在後台操作才會執行 刪除

html
<a href="/delete?id=3"> 刪除 </a>
標題更新時間操作
這是資料2021-12-15

駭客行為

在使用者已登入過後台的情況下,對你發送 釣魚網站惡意連結,在惡意網站內或連結中,寫入下面內容 (假設 後台 網址:https://www.admin.com):

  • 被動

    進入網站後 「點擊」 執行 請求

    html
    <a href="https://www.admin.com/delete?id=3">開始測驗</a>
    

    開始測驗

    當你點下時,就是到了 https://www.admin.com 且送出了 DELETE 指令,刪除了某個東西。

  • 主動

    進入網站時,就 自動送出請求

    html
    <img src="https://www.admin.com/delete?id=3" width="0" height="0" />
    <a href="/test">開始測驗</a>
    

    <img> 設為 隱藏,當網站進入後,就會請求 url,在不知情下就被攻擊了。

POST

如果刪除功能 POST,駭客也可以使用 <form> 來主動提交表單,這是藉由 <iframe> 來隱藏 <form> 的表單顯示。stackoverflow

html
<iframe style="display:none" name="csrf-frame"></iframe>
<form
  method="POST"
  action="https://www.admin.com/delete"
  target="csrf-frame"
  id="csrf-form"
>
  <input type="hidden" name="id" value="3" />
  <input type="submit" value="submit" />
</form>

<script>
  document.getElementById('csrf-form').submit()
</script>

當進入網站,就送出表單。

JSON 傳送

常見與後端溝通的 json ,也是有機會被攻擊,主要是透過 字元 組合達到指定的 json 樣式。

html
<form
  action="https://small-min.blog.com/delete"
  method="post"
  enctype="text/plain"
>
  <input name='{"id":3, "ignore_me":"' value='test"}' type="hidden" />
  <input type="submit" value="delete!" />
</form>

會產生這樣的 請求 body

js
{
  "id": 3,
  "ignore_me": "=test"
}

提醒

但這個攻擊,是發生在 Content-Type: text/plain 的情況下,如果 服務端 有限定類型,是可以避免這個部分。

防禦方式

使用者

一般來說 CSRF 都是發生在使用者己經登入的狀態,才能發動偽造的請求。如果真的要避免,就是使用完網站就登出,這樣是可以避免,但不是很符合人性。

前端

  • 圖形化驗證

    在操作頁加上 圖形化驗証 ,「驗証成功」才可以請求操作,增加了發送請求的難度。

  • Cookie SameSite 同源設置

    在設置 cookie 時,加上 SameSite=Strict 會將 Cookie 限制在的 同源 (當下設置 cookie 的 domain 才可以取得) 情況下使用。

    提醒

    SameSite 的設置,還會影響寫入!!

後端

  • 檢查 Referer

    requestReferer 可以看到發出請求的來源網址,服務端 可以由這位部分來判斷是不是合法的 domain

  • 隱藏的 CSRF TOKEN 欄位

    <form> 表單裡,安插一個 隱藏_csrf 欄位,而這個欄位的值就是由 服務端 所提供的「金鑰 token」,每次提交 請求 時,都會核對這個欄位的「值」是否與 服務端 sessiontoken 相符。 且每次進都都會重新產生「金鑰」。

    html
    <form action="https://small-min.blog.com/delete" method="POST">
      <input type="hidden" name="id" value="3" />
      <input type="hidden" name="_csrf" value="1Zad3aedfaZdadfw" />
      <input type="submit" value="送出" />
    </form>
    

    提示

    express 針對 CSRF 防範的工具 「 csurf 」,就是使用這個作法。

    注意

    若你的 服務端,沒有限制發請求的 domain,還是有可能被駭客拿到這個 token

結論

其實最主要的防範方式,還是要 CSRF 驗証機製 加上 請求來源 來把關,更多層的機制「傷害」可以越低。

Reference