跨站请求伪造(CSRF)-简述
跨站請求偽造(CSRF)-簡述
跨站請求偽造(英語:Cross-site request forgery),也被稱為 one-click attack 或者 session riding,通常縮寫為 或者 XSRF, 是一種挾制用戶在當前已登錄的Web應(yīng)用程序上執(zhí)行非本意的操作的攻擊方法。[1] 跟跨網(wǎng)站腳本(XSS)相比,XSS 利用的是用戶對指定網(wǎng)站的信任,CSRF 利用的是網(wǎng)站對用戶網(wǎng)頁瀏覽器的信任。(維基百科)
當我們請求一個目標網(wǎng)站時,瀏覽器會發(fā)送該目標網(wǎng)站相關(guān)的cookie信息。當我們?yōu)g覽其他的網(wǎng)站時,如果我們沒有退出該目標網(wǎng)站,而其他的網(wǎng)站有一個向目標網(wǎng)站的操作鏈接,這時因為我們在線,且有cookie信息,那么目標網(wǎng)站就會認為這是一個合法的請求而執(zhí)行。但是這個操作不是我們自己請求的,而是惡意者用我們自己被認證過的身份執(zhí)行的操作。
這種惡意的網(wǎng)址并不需要一個特定的網(wǎng)站,它可以藏身在任何一個由用戶生成內(nèi)容的網(wǎng)站中,如論壇,博客等。
如果有賬戶名為Alice的用戶訪問了惡意站點,而她之前剛訪問過在線交易網(wǎng)站,登錄信息尚未過期,那么她就會損失1000資金。
Get方式攻擊:
假設(shè)一個在線交易網(wǎng)站有一個轉(zhuǎn)賬的url:
http://www.examplebank.com/withdraw?account=AccoutName&amount=1000&for=PayeeName一個惡意者在另一個網(wǎng)站添加了如下代碼
<img src="http://www.examplebank.com/withdraw?account=Alice&amount=1000&for=Badman">Post方式攻擊:
//目標網(wǎng)站的form <form id="form" action="withdraw/trans" method="post"><input name="account" type="text"/><input name="amount" type="text"/><input name="forAccount" type="text"/> </form>惡意鏈接
//指向惡意Html的鏈接 <img src="http://other/maliciouspage.html"/>惡意html:
<html><head><script type="text/javascript">window.onload = function () {document.myform.submit(); }</script></head><body><form id="myform" name="myform" action="withdraw/trans" method="post"/><input name="account" type="hidden" value="Alice" /><input name="amount" type="hidden" value="1000"/><input name="forAccount" type="hidden" value="Badman"/></form> </body> </html>惡意Html部署在http://other/maliciouspage.html。惡意鏈接在任何一個可以由用戶生成內(nèi)容的網(wǎng)站,當有用戶是Alice瀏覽到一個有惡意鏈接的網(wǎng)站時,就會加載惡意html,執(zhí)行form方法。
@Html.AntiForgeryToken
如何避免這個惡意請求呢?
既然瀏覽器是不可信的,那么就用一個非瀏覽器的而是跟頁面自身(用戶唯一)才有的唯一隨機值作為驗證對象。
@Html.AntiForgeryToken的驗證流程:
生成驗證值:
當在View中調(diào)用AntiForgeryToken時會先生成一個cookie的名稱,該名稱的前綴為"_RequestVerificationToken"。
如果當前的請求中已有該cookie,則直接對該cookie的值進行序列化(包含加密解密操作)得到AntiForgeryData對象。如果沒有該cookie則生成一個AntiForgeryData對象。
創(chuàng)建cookie,名稱為1中生成的值,值為2中AntiForgeryData對象解析后的字符串(前后值會不一樣,因為還有其他的隨機值作為解析參數(shù))。
@Html.AntiForgeryToken會生成一個名為"_RequestVerificationToken"的隱藏控件,該控件的值是根據(jù)現(xiàn)有的AntiForgeryData對象再創(chuàng)建一個新的AntiForgeryData對象,序列化的字符串。
匹配驗證值:
在form提交時,服務(wù)端會先根據(jù)之前生成cookie的邏輯再次獲取到cookie名稱,如果沒有找到對應(yīng)cookie就拋出異常,如果找到該cookie,就解析解密為AntiForgeryToken對象。
然后在表單中查找名稱為"_RequestVerificationToken"的控件,沒有找到拋出異常,找到的話該控件的值解析解密為AntiForgeryToken對象.
隱藏控件中的AntiForgeryToken和cookie解析解密的AntiForgeryToken對象匹配,一致為合法,不一致為非法。
因為@Html.AntiForgeryToken的值是隨機且加密的,所以惡意html的表單里很難獲取到正確的值。
Cookie:
HTTP/1.1 200 OKCache-Control: privateSet-Cookie: __RequestVerificationToken_L012Y0FwcDEx=EYPOofprbB0og8vI+Pzr1unY0Ye5BihYJgoIYBqzvZDZ+hcT5QUu+fj2hvFUVTTCFAZdjgCPzxwIGsoNdEyD8nSUbgapk8Xp3+ZD8cxguUrgl0lAdFd4ZGWEYzz0IN58l5saPJpuaChVR4QaMNbilNG4y7xiN2/UCrBF80LmPO4=; path=/; HttpOnlyForm:
<form action="..." method="post"> <input name="__RequestVerificationToken" type="hidden" value="yvLaFQ81JVgguKECyF/oQ+pc2/6q0MuLEaF73PvY7pvxaE68lO5qgXZWhfqIk721CBS0SJZjvOjbc7o7GL3SQ3RxIW90no7FcxzR6ohHUYEKdxyfTBuAVjAuoil5miwoY8+6HNoSPbztyhMVvtCsQDtvQfyW1GNa7qvlQSqYxQW7b6nAR2W0OxNi4NgrFEqbMFrD+4CwwAg4PUWpvcQxYA==" /> </form>@Html.AntiForgeryToken的使用:
//Razor: <form id="form" action="withdraw/trans" method="post">@Html.AntiForgeryToken()<input name="account" type="text"/><input name="amount" type="text"/><input name="forAccount" type="text"/> </form>//Controller:添加特性[ValidateAntiForgeryToken]且必須是HttpPost [HttpPost] [ValidateAntiForgeryToken] public ActinResult Trans(string account,double amount,string forAccount) {return View(); }get請求最好是只讀的,對于有操作的請求最好用post來實現(xiàn)。
參考:
Aretch
維基百科
轉(zhuǎn)載于:https://www.cnblogs.com/JoeSnail/p/7743832.html
總結(jié)
以上是生活随笔為你收集整理的跨站请求伪造(CSRF)-简述的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 古罗马皇帝凯撒在打仗时曾经使用过以下方法
- 下一篇: JS-表单验证二