2013-08-22 80 views
0

我有一個asp web應用程序,我想更新以防止跨站點請求僞造攻擊。當使用ajax防止在asp.net web應用程序中的CSRF

我已經使用從VS 2012微軟自動生成的代碼,並且如所描述的here它添加到主頁。它運作良好,但通過Ajax請求一個頁面帖子JSON到一個WebMethod

我想檢查這個Ajax請求爲好。

在可預見的問題是:

var responseCookie = new HttpCookie(AntiXsrfTokenKey) 
    { 
     //Set the HttpOnly property to prevent the cookie from 
     //being accessed by client side script 
       HttpOnly = true, 

這可以明顯改變,但隨後這似乎增加網站的漏洞。這是一個重要的問題?

我可以發送Ajax請求的視圖狀態隱藏輸入的值,但隨後這將需要被解碼成鍵值對做等價的:

(string)ViewState[AntiXsrfTokenKey] != _antiXsrfTokenValue 

有沒有一種簡單的方法使用現有的asp.net方法來做到這一點?

謝謝你的幫助。

+1

創建Html.AntiForgeryToken如果我同樣的方法跟着你,你需要看看System.Web.UI.LosFormatter類,它可以用來從viewstate反序列化 – geedubb

回答

0

這是我發現的。按照geedubb的描述,我最終使用了LosFormatter,將以下代碼添加到MasterPage中,並將該值分配給隱藏的輸入,該輸入通過ajax請求返回。我沒有意識到,當我發佈HttpCookie.HttpOnly屬性仍將ajax請求中的cookie回發的問題時,我可能會將其設置爲false。

internal string GetToken() 
{ 
    // call the static method to guarantee LosFormatter remains threadsafe 
    return GetToken(_antiXsrfTokenValue); 
} 
private static string GetCurrentUserName() 
{ 
    var currentUser = HttpContext.Current.User.Identity; 
    return (currentUser == null) ? string.Empty : currentUser.Name; 
} 
private static string GetToken(string token) 
{ 
    var los = new System.Web.UI.LosFormatter(true, token); 
    var writer = new System.IO.StringWriter(); 
    var data = new Dictionary<string,string>(); 
    data.Add("TokenValue",token); 
    data.Add("UserNameKey", GetCurrentUserName()); 
    los.Serialize(writer, data); 
    return writer.ToString(); 
} 
internal static void Validate(string token) 
{ 
    var request = HttpContext.Current.Request; 
    var requestCookie = request.Cookies[AntiXsrfTokenKey]; 
    var antiXsrfTokenValue = requestCookie.Value; 
    var los = new System.Web.UI.LosFormatter(true, antiXsrfTokenValue); 
    var xsrfData = (Dictionary<string,string>)los.Deserialize(token); 
    if (xsrfData["TokenValue"] != antiXsrfTokenValue || xsrfData["UserNameKey"] != GetCurrentUserName()) 
    { 
     throw new System.Security.Authentication.AuthenticationException("Validation of Anti-XSRF token failed."); 
    } 
} 

最初,我曾試圖發送_VIEWSTATE隱藏輸入的值,使用相同的代碼

 var los = new System.Web.UI.LosFormatter(true, antiXsrfTokenValue); 
     var ajaxViewState = los.Deserialize(token) 

但這扔了一個錯誤,說明所提供的密鑰無法deserialze的字符串。明顯地設置爲

 Page.ViewStateUserKey = _antiXsrfTokenValue; 

具有比單獨提供的密鑰更復雜的密鑰。如果有人知道如何使用userKey反序列化viewstate字符串,我會感興趣。

與我所提供的方法,唯一的問題是字符串的大小調回 - 1976年字符長的GUID + 6個字符的用戶名!!!!

如果再次逼近這個問題,我將引用System.Web.WebPages.dll(在MVC項目中使用),並利用其在MVC

namespace System.Web.Helpers 
{ 
    /// <summary> 
    /// Provides access to the anti-forgery system, which provides protection against 
    /// Cross-site Request Forgery (XSRF, also called CSRF) attacks. 
    /// </summary> 
    public static class AntiForgery 
    { 
     public static void GetTokens(string oldCookieToken, out string newCookieToken, out string formToken) 
     public static void Validate() 
相關問題