20

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.

Naz
  • 1,793
  • 2
  • 13
  • 25

5 Answers5

11

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.)

Richard
  • 106,783
  • 21
  • 203
  • 265
  • 3
    @ShekharPankaj See the [OWASP .NET Security Cheat Sheet](https://www.owasp.org/index.php/.NET_Security_Cheat_Sheet#ASP.NET_Web_Forms_Guidance). Make sure you understand it before integrating (i.e. what it protects you from, and more importantly [what it doesn't protect you from](http://security.stackexchange.com/q/59470)). – tne Dec 14 '15 at 11:48
  • @Richard you should have posted code. what anti-tamper protection do I need in the cookie? encrypt it? how do i do that? – t.durden Nov 14 '19 at 19:49
11

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
Ian Ippolito
  • 486
  • 4
  • 7
  • 1
    Excellent post, but you missed off 3 lines where `AntiXsrfTokenKey` and `AntiXsrfUserNameKey`, and `_antiXsrfTokenValue` is declared. Might be useful to update for some :-) – EvilDr Jul 08 '14 at 13:44
  • @IanIppolito Will this code validates requests that are direct to handler? Because at that time I think this code wont be executed. – Aishwarya Shiva Sep 10 '14 at 15:06
  • Hello Sir, i am using VS2013 and .Net FrameWork 4.5 to create my ASP.net web form app, but my master page does not contain this auto generated code, how do i know if my site is safe from CSRF ? – Nada N. Hantouli Apr 29 '15 at 09:20
  • Can you provide the C# version of this auto generated code ? – Nada N. Hantouli Apr 29 '15 at 12:09
6

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)
    {

    }
}
DavidC
  • 654
  • 1
  • 14
  • 20
  • Is it necessary to validate with the User Identity from the Context? The view state will remain to the state of that page while Context goes on between pages. If the identity change (by browsing with multiple tabs) by the time that the validation is run it will throw an exception since the ViewState won't have changed. – Tristan Dec 21 '17 at 19:47
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.

Zairja
  • 1,441
  • 12
  • 31
Mark Brackett
  • 84,552
  • 17
  • 108
  • 152
1

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

Community
  • 1
  • 1
Keith
  • 150,284
  • 78
  • 298
  • 434