CSRF(Cross Site Request Forgery)
惡意的HTTP指令被當成合法的指令來執行
ps:
CSRF 又稱作 one-click attack
攻擊流程
1.攻擊者準備一個針對網站A的CSRF弱點網頁
2.受害者在網站A是登入狀態,但連到攻擊者的網頁
3.攻擊者的網頁會假冒受害者對網站A發送請求
4.網站A以為是受害者發送的請求,所以用受害者身份執行請求
攻擊原理
CSRF 就是在不同的 domain 底下卻能夠偽造出"使用者本人發出的request".
在瀏覽器的機制,只要發送request到某個網域,就會把相關的資訊一起送過去,例如session id, cookie.
如果使用者在登入狀態,request就會包含了相關登入資訊,就會像使用者本人發出的 request.
實際測透常遇到的問題
- SOP(同源政策)
無法讀取非同源網頁的 Cookie、LocalStorage 和 IndexedDB
無法獲取非同源網頁的 DOM
向非同源地址發送 AJAX 請求,瀏覽器會拒絕響應 - CORS設定太嚴格
- SameSite保護
攻擊範例
GET攻擊範例
正常情況
透過以下GET轉帳100元到帳戶ray
<a href='https://xbank.com/withdraw100?account=ray'>轉帳100</a>
網站後端有做驗證,會確認有沒有登入session,所以只有在本人登入狀態下才會轉帳
攻擊方式1
1.攻擊者準備以下頁面給受害者
<a href='https://xbank.com/withdraw100?account=badguy'>送你500元</a>
2.受害者在登入xbank狀態下開啟攻擊頁面並點擊"送你500元"
瀏覽器會發送一個 GET 請求到https://xbank.com/withdraw100?account=badguy
因為瀏覽器的運作機制,會把xbank.com的登入session等資訊一起送到server端
3.Server端收到後檢查session,確認是受害者本人的請求,於是就把100元轉帳到帳戶badguy
攻擊方式2
1.攻擊者準備以下頁面給受害者
< img src='https://xbank.com/withdraw100?account=badguy' width='0' height='0' />
< a href='/add'>送你500元< /a>
2.受害者在登入xbank狀態下開啟攻擊頁面時,一樣發送轉帳的請求到server端
3.Server端一樣轉帳到帳戶badguy
POST攻擊範例
正常情況
透過以下POST轉帳100元到帳戶ray
< form action="https://xbank.com/withdraw100" method="POST">
< input type="hidden" name="account" value="ray"/>
< input type="submit" value="轉帳"/>
< /form>
網站後端有做驗證,所以會確認有沒有登入session,所以只有在本人登入狀態下才會轉帳
攻擊方式1
1.攻擊者準備以下頁面給受害者
< form action="https://xbank.com/withdraw100" method="POST">
< input type="hidden" name="account" value="badguy "/>
< input type="submit" value="送你500元"/>
< /form>
2.受害者在登入xbank狀態下開啟攻擊頁面並點擊"送你500元",一樣發送轉帳的請求到server端
3.Server端一樣轉帳到帳戶badguy
攻擊方式2
1.攻擊者準備以下頁面給受害者
< iframe style="display:none" name="csrf-frame">< /iframe>
< form method='POST' action='https://xbank.com/withdraw100' target="csrf-frame" id="csrf-form">
< input type='hidden' name='account' value='badguy'>
< input type='submit' value='submit'>
< /form>
< script>document.getElementById("csrf-form").submit()< /script>
這會建一個看不見的 iframe,而且這個form可自動submit
2.受害者在登入xbank狀態下開啟頁面時,自動發送轉帳的請求到server端
3.Server端一樣轉帳到帳戶badguy
refer
https://stackoverflow.com/questions/17940811/example-of-silently-submitting-a-post-form-csrf
結合XSS範例
1.攻擊者在有XSS弱點的留言版插入一段登出指令
...omit< script>.../logout=1 < /script>...omit...
2.受害者在登入狀態下開啟留言版
留言版觸發登出指令,並把此請求傳到server端
3.Server端收到後 ,確認是本人,將使用者強迫登出
歷史上有名的CSRF攻擊案例
Microsoft子網域CSRF變更使用者資訊:
在這個案例中,發現一個缺乏token保護的站點,允許攻擊者進行用戶資訊更改。
Google子網域CSRF刪除帳戶:
此案例中,發現一個有token保護的站點,但在刪除賬戶時,未對token進行正確的校驗,攻擊者僅需提供一個有效的token(自身的token)即可通過校驗。
Facebook CSRF帳號接管:
漏洞利用主要分為兩部分。 第一部分是透過服務端的一個跳轉,第二部分則是Account Takeover(帳號接管)。
MySpace上的蠕蟲Samy:
在MySpace上產生的第一個XSS蠕蟲Samy,其實就是XSS與CSRF結合的結果。 一開始只在Samy的自傳頁面上寫入JavaScript,當有人瀏覽該頁面時,就會在使用者本身的頁面上自動加入「samy is my hero」與散播用的JavaScript。
防禦CSRF
server端防禦
*檢查HTTP Referer
*在請求中加入CSRF token
*圖形驗證碼或簡訊驗證碼等
client端防禦
*SameSite cookie
檢查HTTP Referer
根據 HTTP 協議,HTTP 頭中有一個字段稱為 Referer,它記錄了該 HTTP 請求的來源地址。通常情況下,訪問安全受限頁面的請求來自同一個網站
例如訪問 http://example.bank.com/withdraw?account=bob&amount=1000000&for=Mallory,用戶必須先登錄 example.bank.com,然後通過點擊頁面上的按鈕觸發轉賬事件。這時,該轉帳請求的Referer值將是轉賬按鈕所在頁面的URL,通常是以example.bank.com域名開頭的地址。但如果黑客要對銀行網站實施CSRF攻擊,他只能在他自己的網站構造請求,當用戶通過黑客的網站發送請求到銀行時,該請求的 Referer 指向黑客自己的網站。因此,要防禦 CSRF 攻擊,銀行網站只需對每個轉賬請求驗證其Referer值,如果是以example.bank.com開頭的域名,說明該請求來自銀行網站自己,是合法的。如果 Referer 是其他網站,則可能是 CSRF 攻擊,應該拒絕該請求。然而,這種方法需要注意三個問題:
- 有些瀏覽器可能不攜帶Referer。
- 有些使用者可能關閉自動攜帶Referer 的功能,這將導致伺服器拒絕真實使用者的請求。
- 判定合法域的程式碼必須確保沒有bug。
在請求中加入CSRF token
為了防止CSRF攻擊,可以在請求中添加一個無法被黑客伪造的 token,並在伺服器端建立一個攔截器來驗證該 token。這個 token 可以以參數的形式加入到HTTP請求中,如果請求中沒有 token 或者 token 不正確,則被視為可能是CSRF攻擊而拒絕該請求。
然而,需要注意的是,如果伺服器支援CORS的請求,攻擊者可能仍然可以在他的網頁中發起請求,並成功獲取CSRF token進行攻擊。這取決於伺服器是否接受該網域的請求。
圖形驗證碼或簡訊驗證碼等
類似網路銀行轉帳時要求收取簡訊驗證碼,這樣多了一道檢查可以確保不受CSRF攻擊。圖形驗證碼也能防範攻擊者,因為他們無法知道驗證碼的答案。
SameSite cookie
一些網站使用SameSite cookie來防禦CSRF攻擊。SameSite屬性可用於控制cookie在CSRF攻擊中是否以及如何被提交。透過設置會話cookie的屬性,應用程序可以阻止瀏覽器的默認行為,即自動將cookie添加到請求中,而不管請求來自何處。
refer
http://mycck.blogspot.tw/2008/04/csrf.html
https://www.ithome.com.tw/voice/115822
https://www.ibm.com/developerworks/cn/web/1102_niugang_csrf/index.html
https://blog.techbridge.cc/2017/02/25/csrf-introduction/
https://www.anquanke.com/post/id/204052