WebForms应用程序中的ValidateAntiForgeryToken

问题描述 投票:1回答:3

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

这些是我见过的文章:

ValidateAntiForgeryToken purpose, explanation and example

CSRF and AntiForgeryToken

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

如何在WebForms应用程序中实现此类或类似的东西?

c# asp.net webforms csrf-protection
3个回答
2
投票

CSRF攻击并不是MVC应用程序所独有的,webforms也很容易受到攻击。

基本上,CSRF攻击利用站点在用户浏览器中的信任,通过请求或向网站发布信息,通常通过隐藏的表单或恶意网站内的JavaScript XMLHttpRequests,作为用户使用存储在浏览器中的cookie。

为防止此类攻击,您需要一个防伪令牌,即在您的表单中发送的唯一令牌,您需要在信任表单信息之前进行验证。

你可以找到详细的解释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);
    ...
}

MyMaster.Master:

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

希望你会发现这很有用。


1
投票

使用WebForms,最好的办法是利用ViewStateUserKey

这是怎么做的......

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

SessionID保存在会话变量中似乎有点奇怪,但这是必需的,因为它会在空时自动生成新ID。


0
投票

我发现这篇文章How To Fix Cross-Site Request Forgery (CSRF) using Microsoft .Net ViewStateUserKey and Double Submit Cookie有以下信息代码和说明:

从Visual Studio 2012开始,Microsoft为新的Web表单应用程序项目添加了内置的CSRF保护。要使用此代码,请在解决方案中添加新的ASP .NET Web窗体应用程序,并查看页面后面的Site.Master代码。此解决方案将CSRF保护应用于从Site.Master页面继承的所有内容页面。

此解决方案必须满足以下要求:

•所有进行数据修改的Web表单都必须使用Site.Master页面。

•所有进行数据修改的请求都必须使用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.");
        }
    }
}

}

© www.soinside.com 2019 - 2024. All rights reserved.