Stories

Detail Return Return

最後一次,搞懂CSRF攻擊! - Stories Detail

完整閲讀本文大約需要5分鐘。

開始閲讀之前,先上一道面試題:

CSRF攻擊和XSS攻擊之間,有什麼聯繫?

什麼是CSRF攻擊

CSRF攻擊即Cross-site request forgery,跨站請求偽造,直白來説就是惡意網站偽裝成用户,向被害網站發起操作請求。

為了方便理解,做了一張圖,攻擊流程如下:

  1. 用户登錄受害網站,瀏覽器把獲取的身份憑證保存在本地cookie中;
  2. 用户被誘導打開黑客網站,黑客網站向受害網站服務器發起一個惡意請求,由於cookie的取用規則,這時瀏覽器會自動帶上第一步中的身份憑證;
  3. 受害網站服務端對惡意請求校驗,發現有身份憑證,惡意請求被成功受理;

如果黑客的操作是將用户的錢轉到自己的賬户,那麼這時,他已經卷款跑路了。

如何發起CSRF攻擊

  1. 誘導用户跳轉到黑客網站,網站的HTML中有一個自動提交的隱藏表單,只要用户打開頁面,就會發起轉賬請求;

     <form action="http://bank/transfer" method=POST>
     <input type="hidden" name="account" value="user" />
     <input type="hidden" name="amount" value="10000" />
     <input type="hidden" name="for" value="hacker" />
    </form>
    <script> document.forms[0].submit(); </script> 
  2. 在受害網站的評論區放置一個a標籤,點擊跳轉時發起偽造請求;

    <a href="http://bank/transfer?amount=10000&for=hacker" taget="_blank">
      大八卦
    <a/>
  3. 在受害網站的評論區發表偽裝的圖片,實際是一個惡意請求,瀏覽過評論區的用户都會被黑客攻擊;

    ![風景圖](http://bank/transfer?amount=10000&for=hacker)

怎麼預防CSRF攻擊

CSRF攻擊有兩個特點:

  1. CSRF攻擊的來源通常是黑客網站(外域),因為更好控制;
  2. CSRF攻擊無法獲取用户的身份憑證,只能是冒用;

所以可以想到以下幾個方法:

檢驗請求來源

HTTP 請求頭中有兩個字段會標識請求的來源:originreferer。這兩個字段不受前端控制,會誠實地告訴服務器請求來自哪裏。

origin是請求來源的域名部分,但是在302重定向、以及IE11上不會顯示。

所以還需要referer輔助,它是一個完整的url路徑,但可靠性不如origin

SameSite cookie

CSRF攻擊能成功,正是所有向受害網站發起的請求,都會被自動帶上cookie。

Chrome意識到這個問題後起草了一份協議:向瀏覽器注入cookie時,開發者可以標註哪些請求才會帶上。

被標註為strict的cookie只有本域的請求才能帶上。

被標註為lax的cookie在跳轉到新頁面時可以帶上。因為如果全部設置為strict,在百度搜索並打開淘寶,默認是沒有登錄的,用户體驗會很差。

CSRF Token

在本站發起的請求中,加一個攻擊者無法獲取的token,也可以區別出正常請求和惡意請求。這個token和瀏覽器自動攜帶的cookie不一樣,是需要前端手動帶上的。

但這種方案對服務器壓力較大,需要維護一個session對收到的token做校驗。

雙重cookie

相較於與token,雙重cookie不需要服務器做額外擴容。只需要在請求中加一個額外的字段,其值和cookie一致。因為上文提到過,攻擊者沒法獲取到cookie,只是在發起請求時會攜帶。

在服務端收到請求時,如果沒有和cookie值一樣的額外字段,就可以認為是來自惡意網站。

其他通用方式

CSRF攻擊大多來自第三方網站,但就像上文提到過的鏈接跳轉和圖片偽裝,本站的請求也可能造成威脅。所以我們還需要對UGC內容做一些過濾。

  1. 當前用户打開其他用户填寫的鏈接時,需告知風險;
  2. 不直接使用用户上傳的圖片,先在自己的服務器轉存;

結語

回到開頭提出的問題:

XSS攻擊的核心是注入代碼,獲取用户信息;CSRF攻擊的核心是藉助身份憑證,偽裝用户發起操作請求。

兩者往往是前後出現的:黑客會先通過XSS攻擊獲取到用户的身份憑證,上傳到黑客網站,然後就可以利用它偽裝成用户,發起操作請求。

Add a new Comments

Some HTML is okay.