針對 CSRF 漏洞的防範 [c#,html,webform,mvc,,app api]
最近幫別人“擦屁股”,做了全域性CSRF漏洞修復,針對各種表單,作如下分享(html 為通用方法):
#############################
1.webform
這種情況只需載入一個DLL(Idunno.AntiCsrf.dll),配置web.config即可。
另外一種方法,自己看連結去:http://www.cnblogs.com/luminji/archive/2012/06/08/2511384.html<?xml version="1.0"?> <configuration> <configSections> <section name="csrfSettings" type="Idunno.AntiCsrf.Configuration.CsrfSettings, Idunno.AntiCsrf" /> </configSections> <csrfSettings cookieName="__CSRFCOOKIE" formFieldName="form1" detectionResult="RaiseException" errorPage="" /> <system.web> //iis6 <httpModules> <add name="AntiCSRF" type="Idunno.AntiCsrf.AntiCsrfModule, Idunno.AntiCsrf"/> </httpModules> //iis7 <modules> <add name="AntiCSRF" type="Idunno.AntiCsrf.AntiCsrfModule, Idunno.AntiCsrf"/></modules> </system.web> </configuration> </xml>
#############################
2.mvc
基本思路是利用Token解決,這裡只提供思路
前臺頁面(cshtml):@Html.AntiForgeryToken()
後臺(Controllers):[ValidateAntiForgeryToken]按照這個微軟提供的Token並不能解決問題,發現每次如果抓報文後,依然可以進行二次請求。因Token的驗證機制是頁面生成時,臨時生成一個隱藏域及value值,和一個cookie,提交表單後根據(Request.Form["__RequestVerificationToken"]及cookie值進行計算對比),然而每次請求後微軟自帶Token未銷燬,或者說,僅針對客戶端引數做了驗證。
{
var httpCookie = Request.Cookies["__RequestVerificationToken_Lw__"];
if (httpCookie != null)
{
string cookieRVT = httpCookie.Value;
string rvt = Request.Form["__RequestVerificationToken"];
if (!string.IsNullOrEmpty(rvt))
{
if (this.HttpContext.Session["cookieRVT"] != null && this.HttpContext.Session["rvt"] != null)
{
string temp1 = (string) this.HttpContext.Session["cookieRVT"];
string temp2 = (string)this.HttpContext.Session["rvt"];
if (cookieRVT == temp1 && rvt == temp2)
filterContext.Result = new RedirectResult("/Node/page");
}
}
}
}
protected override void OnActionExecuted(ActionExecutedContext filterContext)
{
var httpCookie = Request.Cookies["__RequestVerificationToken_Lw__"];
if (httpCookie != null)
{
string cookieRVT = httpCookie.Value;
string rvt = Request.Form["__RequestVerificationToken"];
if (!string.IsNullOrEmpty(rvt) && !string.IsNullOrEmpty(cookieRVT))
{
this.HttpContext.Session["cookieRVT"] = cookieRVT;
this.HttpContext.Session["rvt"] = rvt;
}
}
}
#############################
3.html
拋個思路吧,類似上面的cookie及 post 引數驗證, 載入頁面的同時 web端給定兩個值,cookie及非同步填充到隱藏域的值(token表示吧),伺服器端給定兩個session儲存cookie,token。注意的是這兩個值是 通過同一個字串不同的加密方式生成的。提交資料的時候需要提交隱藏域的值,在伺服器獲取cookie 及token做解密或者加密,只要驗證這兩個引數是由同一個字串加密生成的就ok,有且僅當驗證通過,並且cookie,token不等於session儲存值,則視為合法請求,把獲取的值賦值給session;否則視為非法請求,直接pass請求。
#############################
4.app 介面
看了下百度對於app應用,csrf防範,有了基本思路nonce | string | 防範CSRF攻擊的安全認證引數。在輕應用伺服器端生成的隨機串,長度小於32。 |
csrftoken | string | 防範CSRF攻擊的安全認證引數。在輕應用伺服器端按照如下規則生成:md5(nonce + 輕應用的Secret Key) |
思路:使用者登陸成功後返回一個輕應用的Secret Key(也就意味著每次登陸Secret Key都不一樣,伺服器端存session),app每次請求之前請求一次安全認證引數(可逆加密,伺服器端存session),就拿百度的引數nonce來舉例吧,傳送請求的時候帶引數csrftoken,伺服器端驗證,通過後執行請求並修改掉nonce及secret key的session值。