代码之家  ›  专栏  ›  技术社区  ›  Dov Miller

WebForms应用程序中的ValidateAntiForgeryToken

  •  1
  • Dov Miller  · 技术社区  · 6 年前

    我读了一些关于使用 ValidateAntiForgeryToken 防止XSRF/CSRF攻击。然而,我所看到的似乎只与MVC有关。

    以下是我看过的文章:

    ValidateAntiForgeryToken purpose, explanation and example

    CSRF and AntiForgeryToken

    XSRF/CSRF Prevention in ASP.NET MVC and Web Pages

    如何在WebForms应用程序中实现此功能或类似功能?

    3 回复  |  直到 6 年前
        1
  •  5
  •   KYG    6 年前

    CSRF攻击不是MVC应用程序独有的,webforms也是易受攻击的。

    基本上,CSRF攻击利用了网站对用户浏览器的信任,通过请求或向网站发布信息,通常是通过隐藏表单或JavaScript XMLHttpRequests在恶意网站中,就像用户使用浏览器中存储的cookies一样。

    为了防止这种攻击,您需要一个反伪造令牌,一个在表单中发送的唯一令牌,在信任表单的信息之前需要对其进行验证。

    你可以找到详细的解释 here

    为了保护您的webforms应用程序免受CSRF攻击(它在我的项目中起作用),请在您的母版页中实现它,如下所示:

    添加将为您处理CSRF验证的新类:

    public class CsrfHandler
    {
        public static void Validate(Page page, HiddenField forgeryToken)
        {
            if (!page.IsPostBack)
            {
                Guid antiforgeryToken = Guid.NewGuid();
                page.Session["AntiforgeryToken"] = antiforgeryToken;
                forgeryToken.Value = antiforgeryToken.ToString();
            }
            else
            {
                Guid stored = (Guid)page.Session["AntiforgeryToken"];
                Guid sent = new Guid(forgeryToken.Value);
                if (sent != stored)
                {
                    // you can throw an exception, in my case I'm just logging the user out
                    page.Session.Abandon();
                    page.Response.Redirect("~/Default.aspx");
                }
            }
        }
    }
    

    MyMasterPage.Master.cs:

    protected void Page_Load(object sender, EventArgs e)
    {
        CsrfHandler.Validate(this.Page, forgeryToken);
        ...
    }
    

    我的主人。主人:

    <form id="form1" runat="server">
        <asp:ScriptManager ID="ScriptManager1" runat="server"></asp:ScriptManager>
        <asp:HiddenField ID="forgeryToken" runat="server"/>
        ...
    </form>
    

    希望你会发现这个有用。

        2
  •  3
  •   Dov Miller    6 年前

    How To Fix Cross-Site Request Forgery (CSRF) using Microsoft .Net ViewStateUserKey and Double Submit Cookie 带有以下信息代码和说明:

    要使此解决方案工作,必须满足以下要求:

    第页。

    进行数据修改的所有请求都必须使用ViewState。

    网站必须没有任何跨站点脚本(XSS) how to fix Cross-Site Scripting (XSS) using Microsoft .Net Web Protection Library

    public partial class SiteMaster : MasterPage
    {
    private const string AntiXsrfTokenKey = "__AntiXsrfToken";
    private const string AntiXsrfUserNameKey = "__AntiXsrfUserName";
    private string _antiXsrfTokenValue;
    
    protected void Page_Init(object sender, EventArgs e)
    {
        //First, check for the existence of the Anti-XSS cookie
        var requestCookie = Request.Cookies[AntiXsrfTokenKey];
        Guid requestCookieGuidValue;
    
        //If the CSRF cookie is found, parse the token from the cookie.
        //Then, set the global page variable and view state user
        //key. The global variable will be used to validate that it matches in the view state form field in the Page.PreLoad
        //method.
        if (requestCookie != null
        && Guid.TryParse(requestCookie.Value, out requestCookieGuidValue))
        {
            //Set the global token variable so the cookie value can be
            //validated against the value in the view state form field in
            //the Page.PreLoad method.
            _antiXsrfTokenValue = requestCookie.Value;
    
            //Set the view state user key, which will be validated by the
            //framework during each request
            Page.ViewStateUserKey = _antiXsrfTokenValue;
        }
        //If the CSRF cookie is not found, then this is a new session.
        else
        {
            //Generate a new Anti-XSRF token
            _antiXsrfTokenValue = Guid.NewGuid().ToString("N");
    
            //Set the view state user key, which will be validated by the
            //framework during each request
            Page.ViewStateUserKey = _antiXsrfTokenValue;
    
            //Create the non-persistent CSRF cookie
            var responseCookie = new HttpCookie(AntiXsrfTokenKey)
            {
                //Set the HttpOnly property to prevent the cookie from
                //being accessed by client side script
                HttpOnly = true,
    
                //Add the Anti-XSRF token to the cookie value
                Value = _antiXsrfTokenValue
            };
    
            //If we are using SSL, the cookie should be set to secure to
            //prevent it from being sent over HTTP connections
            if (FormsAuthentication.RequireSSL &&
            Request.IsSecureConnection)
            responseCookie.Secure = true;
    
            //Add the CSRF cookie to the response
            Response.Cookies.Set(responseCookie);
        }
    
            Page.PreLoad += master_Page_PreLoad;
        }
    
        protected void master_Page_PreLoad(object sender, EventArgs e)
        {
            //During the initial page load, add the Anti-XSRF token and user
            //name to the ViewState
            if (!IsPostBack)
            {
                //Set Anti-XSRF token
                ViewState[AntiXsrfTokenKey] = Page.ViewStateUserKey;
    
                //If a user name is assigned, set the user name
                ViewState[AntiXsrfUserNameKey] =
                Context.User.Identity.Name ?? String.Empty;
            }
            //During all subsequent post backs to the page, the token value from
            //the cookie should be validated against the token in the view state
            //form field. Additionally user name should be compared to the
            //authenticated users name
            else
            {
                //Validate the Anti-XSRF token
                if ((string)ViewState[AntiXsrfTokenKey] != _antiXsrfTokenValue
                || (string)ViewState[AntiXsrfUserNameKey] !=
                (Context.User.Identity.Name ?? String.Empty))
            {
            throw new InvalidOperationException("Validation of
            Anti-XSRF token failed.");
            }
        }
    }
    

    }

        3
  •  1
  •   dana    6 年前

    使用WebForms,最好的方法是利用 ViewStateUserKey .

    void Page_Init(object sender, EventArgs args)
    {    
        ViewStateUserKey = (string)(Session["SessionID"] = Session.SessionID);
    }
    

    拯救世界似乎有点奇怪 SessionID 但这是必需的,因为它将在空时自动生成一个新ID。