1. 程式人生 > >針對 CSRF 漏洞的防範 [c#,html,webform,mvc,,app api]

針對 CSRF 漏洞的防範 [c#,html,webform,mvc,,app api]

最近幫別人“擦屁股”,做了全域性CSRF漏洞修復,針對各種表單,作如下分享(html 為通用方法):


#############################

1.webform

這種情況只需載入一個DLL(Idunno.AntiCsrf.dll),配置web.config即可。

<?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>
另外一種方法,自己看連結去:http://www.cnblogs.com/luminji/archive/2012/06/08/2511384.html

#############################

2.mvc

基本思路是利用Token解決,這裡只提供思路

前臺頁面(cshtml):@Html.AntiForgeryToken()

後臺(Controllers):[ValidateAntiForgeryToken]

按照這個微軟提供的Token並不能解決問題,發現每次如果抓報文後,依然可以進行二次請求。因Token的驗證機制是頁面生成時,臨時生成一個隱藏域及value值,和一個cookie,提交表單後根據(Request.Form["__RequestVerificationToken"]及cookie值進行計算對比),然而每次請求後微軟自帶Token未銷燬,或者說,僅針對客戶端引數做了驗證。

解決辦法: protected override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            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值。