Generating AntiForgeryToken in WebForms

24,859

Solution 1

Implementing it yourself is not too difficult.

  • Generate a GUID
  • Put it in a hidden field
  • Also put it in Session or Cookie (in the latter case, with some anti-tamper protection)
  • At the start of processing the form compare the field and stored token.

(If you look at the implementation of MVC, there is very little more to it. A few helper methods is all you need.)

Solution 2

This is an old question, but the latest Visual Studio 2012 ASP.NET template for web forms includes anti CSRF code baked into the master page. If you don't have the templates, here's the code it generates:

Protected Sub Page_Init(sender As Object, e As System.EventArgs)


    ' The code below helps to protect against XSRF attacks
    Dim requestCookie As HttpCookie = Request.Cookies(AntiXsrfTokenKey)
    Dim requestCookieGuidValue As Guid
    If ((Not requestCookie Is Nothing) AndAlso Guid.TryParse(requestCookie.Value, requestCookieGuidValue)) Then
        ' Use the Anti-XSRF token from the cookie
        _antiXsrfTokenValue = requestCookie.Value
        Page.ViewStateUserKey = _antiXsrfTokenValue
    Else
        ' Generate a new Anti-XSRF token and save to the cookie
        _antiXsrfTokenValue = Guid.NewGuid().ToString("N")
        Page.ViewStateUserKey = _antiXsrfTokenValue

        Dim responseCookie As HttpCookie = New HttpCookie(AntiXsrfTokenKey) With {.HttpOnly = True, .Value = _antiXsrfTokenValue}
        If (FormsAuthentication.RequireSSL And Request.IsSecureConnection) Then
            responseCookie.Secure = True
        End If
        Response.Cookies.Set(responseCookie)
    End If

    AddHandler Page.PreLoad, AddressOf master_Page_PreLoad
End Sub

Private Sub master_Page_PreLoad(sender As Object, e As System.EventArgs)


    If (Not IsPostBack) Then
        ' Set Anti-XSRF token
        ViewState(AntiXsrfTokenKey) = Page.ViewStateUserKey
        ViewState(AntiXsrfUserNameKey) = If(Context.User.Identity.Name, String.Empty)
    Else
        ' Validate the Anti-XSRF token
        If (Not DirectCast(ViewState(AntiXsrfTokenKey), String) = _antiXsrfTokenValue _
            Or Not DirectCast(ViewState(AntiXsrfUserNameKey), String) = If(Context.User.Identity.Name, String.Empty)) Then
            Throw New InvalidOperationException("Validation of Anti-XSRF token failed.")
        End If
    End If
End Sub

Solution 3

The C# version of Ian Ippolito answer here:

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)
    {
        // The code below helps to protect against XSRF attacks
        var requestCookie = Request.Cookies[AntiXsrfTokenKey];
        Guid requestCookieGuidValue;
        if (requestCookie != null && Guid.TryParse(requestCookie.Value, out requestCookieGuidValue))
        {
            // Use the Anti-XSRF token from the cookie
            _antiXsrfTokenValue = requestCookie.Value;
            Page.ViewStateUserKey = _antiXsrfTokenValue;
        }
        else
        {
            // Generate a new Anti-XSRF token and save to the cookie
            _antiXsrfTokenValue = Guid.NewGuid().ToString("N");
            Page.ViewStateUserKey = _antiXsrfTokenValue;

            var responseCookie = new HttpCookie(AntiXsrfTokenKey)
            {
                HttpOnly = true,
                Value = _antiXsrfTokenValue
            };
            if (FormsAuthentication.RequireSSL && Request.IsSecureConnection)
            {
                responseCookie.Secure = true;
            }
            Response.Cookies.Set(responseCookie);
        }

        Page.PreLoad += master_Page_PreLoad;
    }

    protected void master_Page_PreLoad(object sender, EventArgs e)
    {
        if (!IsPostBack)
        {
            // Set Anti-XSRF token
            ViewState[AntiXsrfTokenKey] = Page.ViewStateUserKey;
            ViewState[AntiXsrfUserNameKey] = Context.User.Identity.Name ?? String.Empty;
        }
        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.");
            }
        }
    }

    protected void Page_Load(object sender, EventArgs e)
    {

    }
}

Solution 4

WebForms has a pretty similar analog in Page.ViewStateUserKey. By setting that to a per-user value (most choose HttpSessionState.SessionId), WebForms will validate the ViewState1 as part of the MAC check.

 overrides OnInit(EventArgs e) {
     base.OnInit(e);
     ViewStateUserKey = Session.SessionId;
 }

1 There are scenarios where ViewStateUserKey will not help. Mainly, they boil down to doing dangerous things with GET requests (or in Page_Load without checking IsPostback), or disabling ViewStateMAC.

Solution 5

You can use reflection to get at the MVC methods used to set the cookie and matching form input used for the MVC validation. That way you can have an MVC action with [AcceptVerbs(HttpVerbs.Post), ValidateAntiForgeryToken] attributes that you can post to from a WebForms generated page.

See this answer: Using an MVC HtmlHelper from a WebForm

Share:
24,859
Naz
Author by

Naz

Web developer for a recruitment website.

Updated on July 05, 2022

Comments

  • Naz
    Naz almost 2 years

    I have a .NET Webforms site thanks needs to post to my MVC Application which currently sits inside the Webform site as a separate application.

    The Webform application need to POST some sensitive values to the MVC Application.

    Is there a way to generate a AntiForgeryToken() in my WebForms Application so it can be passed with the form post.

    Otherwise does anyone know of any other custom anti forgery code that will allow me to do something similar to the MVC's AntiForgeryValidation.