He leído un poco sobre el uso de ValidateAntiForgeryToken para prevenir ataques XSRF / CSRF. Sin embargo, lo que he visto parece relacionarse solo con MVC.

Estos son los artículos que he visto:

ValidateAntiForgeryToken propósito, explicación y ejemplo

CSRF y AntiForgeryToken

Prevención XSRF / CSRF en ASP.NET MVC y páginas web

¿Cómo puedo implementar esto o algo similar en una aplicación WebForms?

2
Dov Miller 13 sep. 2018 a las 16:52

3 respuestas

La mejor respuesta

Encontré este artículo Cómo solucionar la falsificación de solicitudes entre sitios (CSRF) ) utilizando Microsoft .Net ViewStateUserKey y Double Submit Cookie con el siguiente código de información e instrucciones:

A partir de Visual Studio 2012, Microsoft agregó protección CSRF integrada a los nuevos proyectos de aplicaciones de formularios web. Para utilizar este código, agregue una nueva aplicación de formularios web ASP .NET a su solución y vea el código Site.Master detrás de la página. Esta solución aplicará la protección CSRF a todas las páginas de contenido que hereden de la página Site.Master.

Deben cumplirse los siguientes requisitos para que esta solución funcione:

• Todos los formularios web que realicen modificaciones de datos deben usar la página Site.Master.

• Todas las solicitudes que realicen modificaciones de datos deben usar ViewState.

• El sitio web debe estar libre de todas las secuencias de comandos entre sitios (XSS) vulnerabilidades Consulte cómo solucionar Cross-Site Scripting (XSS) utilizando Microsoft .Net Web Protection Library para más detalles.

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

}

1
Dov Miller 16 sep. 2018 a las 10:39

Con WebForms, lo mejor que puede hacer es aprovechar ViewStateUserKey.

Aquí está cómo hacerlo ...

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

Parece extraño guardar el SessionID en una variable de sesión, pero esto es necesario porque generará automáticamente una nueva ID cuando esté vacío.

1
dana 14 sep. 2018 a las 16:46

Los ataques CSRF no son exclusivos de la aplicación MVC, los formularios web también son vulnerables.

Básicamente, el ataque CSRF explota la confianza que un sitio tiene en el navegador de un usuario, al solicitar o publicar información en el sitio web, generalmente a través de formularios ocultos o JavaScript XMLHttpRequests dentro de un sitio web malicioso, como usuario que utiliza cookies almacenadas en el navegador.

Para evitar estos ataques, necesitará un token antiforgery, un token único enviado dentro de sus formularios, que debe validar antes de confiar en la información del formulario.

Puede encontrar una explicación detallada aquí.

Para proteger sus aplicaciones de formularios web contra ataques CSRF (está funcionando en mis proyectos), es implementarlo en sus páginas maestras, de esta manera:

Agregue una nueva clase que manejará las validaciones CSRF por usted:

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

Luego implemente esto en sus páginas maestras:

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>

Espero que encuentres esto útil.

5
KYG 14 sep. 2018 a las 07:31