<style> .red{ color:red; } .blue{ color:blue; } </style> # LeetCode讀書會(7/22~7/29)CSRF ## 本週主題:CSRF ------宇軒------ ### 什麼是CSRF CSRF攻擊的核心為跨域請求,攻擊者利用網站對使用者瀏覽器cookie的信任來製造攻擊,例如網行會提供使用者進行轉帳服務,攻擊者可以自己建立網站並在點擊處塞入「向網行發送轉帳到特定帳戶的要求」,並傳送網站連結到各處誘使該網銀的用戶點擊,當使用者點擊連結而使用者的驗證cookie還存在的時候,網站後端會判定該請求為使用者主動發送的,並將金額轉帳到攻擊者的帳戶,成功進行跨域攻擊。 ### CSRF的防禦方法 1. **二次驗證**:在重要的操作功能增加圖形驗證、簡訊驗證。就能直接抵擋CSRF攻擊,但這樣的二次驗證不應再太多功能上使用,因為驗證會增加使用者操作的負擔。 2. **CSRF token**:在要輸入的表單中塞入叫```csrftoken```的隱藏欄位,```csrftoken```的值由server隨機產生,同時讓client side設定一名為```csrftoken```的cookie,值也是同一組token。當使用者送出表單的時候,server就可以比對cookie的csrftoken和form的csrftoken,檢查是否有值且是否相等,判斷是不是真的由使用者發出的要求。因為攻擊者不能在自己的網域設定攻擊對象網域的cookie,如此一來CSRF攻擊所發出來的request就不會有csrftoken的cookie而被擋下來。 3. **SameSite Cookie**:為瀏覽器開發的功能,讓cookie只能從相同網域發起的請求一起發送,避免從而避免跨域攻擊。目前大多數瀏覽器(除了IE)都已經有支援SameSite cookie的設定([資料來源:MDN](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie/SameSite#browser_compatibility))。模式又分為strict和lax。 1. strict模式:只有從同域發送的請求才能夾帶cookie,但這樣若是從別的地方點擊連結進入網頁就定不會是登入狀態(沒辦法傳cookie),使用者便利性變很低。 3. lax模式:放寬部分限制,例如```<a> <link rel='XX'>``` 還是能帶上cookie,但POST、PUT、DELETE則不會帶上cookie,這樣使用者從別的網域連進網站時依然能保留登入狀態,在進行重要操作時仍有同域的限制,不會影響使用者的網站體驗。lax模式也是目前多數瀏覽器SameSite的預設值。 SameSite設置方式如下: ``` Set-Cookie : session_id = qiwjfd1jwidjw02; SameSite ``` ### 參考資料: [讓我們來談談 CSRF - Huli](https://blog.techbridge.cc/2017/02/25/csrf-introduction/) [身為 Web 工程師,你一定要知道的幾個 Web 資訊安全議題 - 莫立全](https://medium.com/starbugs/%E8%BA%AB%E7%82%BA-web-%E5%B7%A5%E7%A8%8B%E5%B8%AB-%E4%BD%A0%E4%B8%80%E5%AE%9A%E8%A6%81%E7%9F%A5%E9%81%93%E7%9A%84%E5%B9%BE%E5%80%8B-web-%E8%B3%87%E8%A8%8A%E5%AE%89%E5%85%A8%E8%AD%B0%E9%A1%8C-29b8a4af6e13) [SameSite cookies - MDN](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie/SameSite) ------宇軒------ ------瑋晨------   --> 待解決: cookie 可不可以設置只有某個網站來的cookie才有效?? ex. referer (但似乎有瀏覽器可以竄改referer) --> 另一種方法,在進行敏感操作的時候,後端會檢查token,token可以放在redis?  ------瑋晨------ -----承翰------- <br> 普遍防禦CSRF的方法有兩種: 1、檢查 referer欄位 2、加入驗證token ### 檢查referer欄位 這個方法很簡單,既然攻擊是來自於非銀行網站,那我就確認需求的來源就行了,而http協定中就有一個referer欄位記錄著這個請求是從哪個網站發出來的,只要不是銀行網站發出來的請求,網站這邊一律不接受! 依照這樣的方式,我們可以用快速且低成本的方式來防範CSRF,只是有個問題,就是駭客能否偽造這個referer欄位呢? 如果他也可以偽裝成銀行來源,那用戶就還是會被攻擊。顯然這種方法只能初步防禦CSRF,碰到進階一點的攻擊手法就會再度被破解。 ### 加入驗證token CSRF的核心概念,就是銀行不知道發出請求的人是不是攻擊者,那按照這個思路,只要使用者能提出一個唯一且保密的序號,攻擊者拿不到這個序號,自然就不能偽裝成使用者,而這個序號,就是我們稱的CSRF Token,這個Token是由銀行server產生,並且加密存在session中的,其他人無法仿造,只有透過server給使用者,並在一定時間內刷新。當使用者想做任何交易的時候,銀行server就會請使用者提供CSRF Token,如果不能提供,就代表這次的請求就是攻擊者,那銀行server就不予理會。 資料來源:https://medium.com/@Tommmmm/csrf-%E6%94%BB%E6%93%8A%E5%8E%9F%E7%90%86-d0f2a51810ca ### 要理解samesite前,需要知道甚麼是site <p>以github.io為例,gitgub.io是後綴字元,a.github.io才是一個完整的site,<span class='blue'>a.github.io</span>跟<span class='red'>b.github.io</span>為不同的site</p> <a href='https://publicsuffix.org/list/public_suffix_list.dat'>site字尾一覽表</a> <br> -----承翰------- ------重鈞------- ### CSRF Events: ``` 1.三星官網介面出現 CSRF,險成會員帳號劫持途徑 a.事件大綱:Samsung 手機用戶的身分驗證,經烏克蘭軟體抓漏好手 Artem Moskowsky 測試後,下列 3 項漏洞 CSRF 均可奏效: (1)能窺伺、竄改用戶個資 (2)停用 2-factor authentication 身分驗證 (3)強行置換安全提問與答案,重設密碼後假冒受害者身分 b.原因: (1)對於來自用戶端的請求,只依賴表頭 "referer" 參數提供資料加以辨識。 c.解決方案: (1)Samsung 已更正 web 入口網站安全性設計 d.賞金:$13300 e.備註:Artem Moskowsky 還曾被 Steam 合作的遊戲開發公司 Valve 贈予 $20000 (激活碼 Bug),及被 Steamworks 贈予 $25000 (SQL injection) ``` ``` 2.長庚大學--【漏洞預警】電子學習平台 Moodle 出現嚴重 CSRF 缺陷,請儘速確認並進行修正 a.事件大綱: 開源電子學習平臺 Moodle 出現跨站請求偽造漏洞,能讓使用者身分驗證後與 Moodle 連線的期間,被有心人士冒名操作。 b.原因: (1)Moodle 登入表單的安全機制中,伺服器端的 authenticate_user_login( ) 函數預設並未啟動,缺少 Token 檢驗。 (2)若攻擊者加入新的組態參數 $CFG->disablelogintoken,就能製造 CSRF,迴避 Moodle 對所有表單內的 Token 內容偵測。 c.解決方案: (1)針對 token 漏洞進行版本更新 ``` ``` 3.求職網站 Glassdoor 關鍵 CSRF 漏洞 a.事件大綱:Glassdoor 主要有以下漏洞: (1)攻擊者可任意控制求職者個人資料(編輯、新增或刪除等等) (2)攻擊者可任意控制雇主帳戶(發布或刪除工作) (3)有可能得到對 Glassdoor 公司帳戶的管理權限,且受害者可被誘導到惡意連結 "Tabahi"。 b.原因: (1)攻擊者透過生成「從帳戶 A 中生成 CSRF token,去掉第一個字符 underscore(_),並使用 token 作為帳戶 B 的 CSRF token」以繞過驗證機制。 (2)伺服器在驗證 token 時,已經判定 A token 有效。即便去掉一個字符使長度不等於 153(B token),仍錯誤地判定為有效。 (3)Fake token 觸發 Error 時,卻沒有 response Fail,反而僅記錄下來並允許繼續操作。 c.解決方案: (1)Glassdoor 改為觸發 Error 時會 response 403 d.賞金:$3000 ``` ### 參考資料: 1-1. [台灣電腦網路危機處理暨協調中心 - TWCERT/CC ](https://www.facebook.com/twcertcc/posts/2288611908035208/) 1-2. [Samsung fixes flaws that could have let attackers hijack your account](https://nakedsecurity.sophos.com/2018/12/12/samsung-fixes-flaws-that-could-have-let-attackers-hijack-your-account/?fbclid=IwAR1iJva32H9JtjOugvoI_JnlVZrRVVBXYDYX_iX2VuednWqR4p1tPsvV1wc) 1-3. [Steam出現重大Bug,可以獲取任意遊戲激活碼!](https://kknews.cc/zh-tw/game/mojv8az.html) 2. [長庚大學 -- 電子學習平台 Moodle 出現嚴重 CSRF 缺陷](https://ic.cgu.edu.tw/p/406-1016-61050,r62.php?Lang=zh-tw) 3-1. [Critical CSRF flaw in Glassdoor nets security researcher $3,000 bug bounty](https://portswigger.net/daily-swig/critical-csrf-flaw-in-glassdoor-nets-security-researcher-3-000-bug-bounty) 3-2. [SITE WIDE CSRF ON GLASSDOOR](https://blog.witcoat.com/2020/12/03/site-wide-csrf-on-glassdoor/) ------重鈞------- ------震瑋------- ### Cross Site Request Forgery 是什麼 跨站偽造請求(cross-site request forgery)也稱為 one-click attack 或 session riding,通常縮寫為 CSRF(有時發音為 sea-surf) 或 XSRF,這是一種利用伺服器所信任的網站來發送惡意請求的攻擊;和 cross-site scripting (XSS) 不同,XSS 是透過在網站上輸入惡意程式碼的方式來進行攻擊,通常利用的是「使用者對目標網站」的信任;而 CSRF 則是攻擊者利用「目標網站對該信用者」的信任。透過 CSRF 攻擊有機會讓使用者在無意間修改受害者的帳號密碼,或將帳戶內的金額轉帳給攻擊者。 CSRF 通常有以下流程: - 使用者使用正常流程登入「目標網站」 - 「惡意網站」利用目標網站對使用者的信任(credentials),例如 Cookies - 欺騙使用者到「惡意網站」後,誘使使用者點擊某個按鈕,但這個按鈕可能會送出表單,而該表單的請求對象是對到「目標網站」 - 瀏覽器預設會把使用者在「目標網站」的 Cookie 連帶送出,因此雖然該請求是在「惡意網站」發出,但「目標網站」收到請求時因為帶有 credentials,所以會誤以為是合法的請求。 ### 攻擊範例 使用者一旦點擊下方的連結,即會向「目標網站」送出 Post 請求: ```html <!-- - Code from Rails Guides - https://guides.rubyonrails.org/security.html#cross-site-request-forgery-csrf --> <a href="http://www.harmless.com/" onclick=" var f = document.createElement('form'); f.style.display = 'none'; this.parentNode.appendChild(f); f.method = 'POST'; f.action = 'http://www.example.com/account/destroy'; f.submit(); return false;" >To the harmless survey</a> ``` 或者使用者只要將滑鼠移過某一張圖片時,即透過 JavaScript 執行指令: ```html <!-- - Code from Rails Guides - https://guides.rubyonrails.org/security.html#cross-site-request-forgery-csrf --> <img src="http://www.harmless.com/img" width="400" height="400" onmouseover="..." /> ``` ### 預防範例 兩種 Flask 實作避免 CSRF 攻擊的方法,分別是 CSRF token 和 SameSite cookie: #### 方法一、CSRF token 為了解決來源信任問題,由 Server 產生 token 存放在 session 中,並在前端頁面中所有表單加上一個 hidden 的欄位放 token,當 Server 接收到使用者發送的請求時,會驗證 session 中的 token 與請求中的 token 是否相同,來判斷請求來源是否是可信。 ```python import os from flask_wtf.csrf import CSRFProtect app.config['SECRET_KEY'] = os.urandom(24) csrf = CSRFProtect(app) ``` 在所有表單中加入 hidden 欄位 csrf_token ```html <form method="post"> <input type="hidden" name="csrf_token" value="{{ csrf_token() }}"/> <input type="text" name="email" class="form-control form-control-lg" placeholder="max@email.com"> </form> ``` 如果是使用 ajax 或 axios 可在 header 中加入 csrf-token ```html <script> var csrf = "{{ csrf_token() }}"; axios.post('/auth/login', data, { headers: {'x-csrf-token': csrf} }) </script> ``` 這個方法,之所以有用是因為 form 表單的 token 雖然可以隨便修改,但攻擊者並不知道正確的 csrf_token 值是什麼,也沒辦法猜到,兩者不可能匹配, request 就不被信任,所以自然就無法進行攻擊了。 #### 方法二、SameSite cookie SameSite 的用途為防止瀏覽器因跨站請求傳送 cookies,目的是降低跨站資料外洩與 CSRF 攻擊的風險。SameSite 設有三個數值層級,分別為 Strict, Lax 和 None,由嚴格至寬鬆不同程度地限制 cookies 的傳輸。 當 cookie 中設定了 SameSite = ‘Strict’ 的話,代表著這個 cookie 只允許 same site 情況下使用。 但目前並非所有的瀏覽器版本都支持 SameSite 的功能,所以並非加上了 SameSite=’Strict’ 就可以完全避免 CSRF 的攻擊。 [Can I use samesite](https://caniuse.com/?search=samesite) ```python= @app.route("/set") def setcookie(): resp = make_response('Setting cookie!') resp.set_cookie(key='framework', value='flask', expires=time.time()+6*60, httponly=True, samesite='Strict') return resp ``` - httponly:如設定為 True,表示 JavaScript 的Document.cookie API 無法取得 HttpOnly cookies - samesite:可以設定成 Strict、Lax 和 None ### 參考資料 [CSRF說明與預防](https://pjchender.blogspot.com/2020/05/cross-site-request-forger-csrf-xsrf.html) [實作 Flask CSRF Protection](https://www.maxlist.xyz/2020/05/07/flask-csrf/) ------震瑋------- ## LeetCode卡關區
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up