【问题标题】:How to prevent CSRF attack in ASP.Net Web Application?如何防止 ASP.Net Web 应用程序中的 CSRF 攻击?
【发布时间】:2015-01-15 12:35:42
【问题描述】:

我想防止我的 Web 应用程序受到 CSRF 攻击。

我在母版页中应用此解决方案,所有网页都继承自此母版页。

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.");
            }
        }
    }
}

使用此解决方案,我无法实现我想要的。

如果用户 A 登录,执行一些活动并从 Fiddler 捕获请求并注销,现在用户 B 登录,我触发捕获的请求并成功完成任务。所以我的申请没有被阻止。

我可以看到 Request.Cookies[AntiXsrfTokenKey] 值对于特定会话是相同的,而对于新会话 Request.Cookies[AntiXsrfTokenKey] 值是不同的。

这行我该怎么办

throw new InvalidOperationException("Validation of Anti-XSRF token failed.");

在注销按钮上单击我清除所有内容。

 FormsAuthentication.SignOut();

        Session.Clear();
        Session.Abandon();
        Session.RemoveAll();

        HttpCookie cookies = Context.Request.Cookies[FormsAuthentication.FormsCookieName];//Or Response
        cookies.Expires = DateTime.Now.AddDays(-1);
        Context.Response.Cookies.Add(cookies);

        if (Request.Cookies["ASP.NET_SessionId"] != null)
        {
            Response.Cookies["ASP.NET_SessionId"].Value = string.Empty;
            Response.Cookies["ASP.NET_SessionId"].Expires = DateTime.Now.AddMonths(-20);
        }

        if (Request.Cookies["AuthToken"] != null)
        {
            Response.Cookies["AuthToken"].Value = string.Empty;
            Response.Cookies["AuthToken"].Expires = DateTime.Now.AddMonths(-20);
        }

        if (Request.Cookies[AntiXsrfTokenKey] != null)
        {
            Response.Cookies[AntiXsrfTokenKey].Value = string.Empty;
            Response.Cookies[AntiXsrfTokenKey].Expires = DateTime.Now.AddMonths(-20);
        }


        //Response.Redirect("Logon.aspx");
        FormsAuthentication.RedirectToLoginPage();

【问题讨论】:

    标签: c# asp.net cookies session-cookies csrf


    【解决方案1】:

    只需在发送数据的表单中添加@Html.AntiForgeryToken()。然后用[ValidateAntiForgeryToken]装饰action方法或控制器:msdn

    【讨论】:

    • 它不是基于 MVC 的,它的 asp.net 4.0
    【解决方案2】:

    【讨论】:

    • 它不是基于 MVC 的,它的 asp.net 4.0
    猜你喜欢
    • 2013-05-08
    • 2011-03-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-26
    • 1970-01-01
    • 2018-01-08
    • 2015-09-28
    相关资源
    最近更新 更多