asp.net - forgery - csrf c#
prevenir ataques de falsificación de solicitudes entre sitios(csrf) en los formularios web de asp.net (4)
Cuando crea un nuevo proyecto de ''Aplicación de formulario web'' en VS 2013, site.master.cs incluirá automáticamente el código XSRF / CSRF en la sección Page_Init
de la clase. Si aún no obtiene el código generado, puede Copy
y Paste
manualmente el código. Si está usando C #, entonces use el siguiente:
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.");
}
}
}
He creado una aplicación de formularios web ASP.Net con Visual Studio 2013 y estoy utilizando .NET Framework 4.5. Quiero asegurarme de que mi sitio esté seguro frente a la falsificación de solicitudes entre sitios (CSRF, por sus siglas en inglés). He encontrado muchos artículos que hablan sobre cómo se implementa esta función en las aplicaciones MVC, pero muy pocos sobre los formularios web. En esta pregunta de StackOverflow, un comentario indica que
"Esta es una pregunta antigua, pero la última plantilla de Visual Studio 2012 ASP.NET para formularios web incluye código anti-CSRF integrado en la página maestra. Si no tiene las plantillas, aquí está el código que genera: ..."
Mi página maestra no contiene el código mencionado en esa respuesta. ¿Está realmente incluido en las nuevas aplicaciones? Si no, ¿cuál es la mejor manera de agregarlo?
Podrías probar lo siguiente. En el formulario web agregue:
<%= System.Web.Helpers.AntiForgery.GetHtml() %>
Esto agregará un campo oculto y una cookie. Por lo tanto, si completa algunos datos del formulario y los envía al servidor, necesita una comprobación simple:
protected void Page_Load(object sender, EventArgs e)
{
if (IsPostBack)
AntiForgery.Validate();
}
AntiForgery.Validate();
lanza una excepción si falla la comprobación anti XSFR.
Puede usar el siguiente código, que verificará la solicitud de dónde viene
if ((context.Request.UrlReferrer == null || context.Request.Url.Host != context.Request.UrlReferrer.Host))
{
context.Response.Redirect("~/error.aspx", false);
}
¡¡¡Funciona muy bien para mí!!!
ViewStateUserKey y Double Submit Cookie
A partir de Visual Studio 2012, Microsoft agregó protección CSRF incorporada a 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. Esta solución aplicará la protección CSRF a todas las páginas de contenido que heredan de la página de Site.Master.
Se deben cumplir los siguientes requisitos para que esta solución funcione:
Todos los formularios web que realicen modificaciones de datos deben utilizar la página Site.Master. Todas las solicitudes que realizan modificaciones de datos deben utilizar ViewState. El sitio web debe estar libre de todas las vulnerabilidades de secuencias de comandos entre sitios (XSS). Vea cómo corregir las secuencias de comandos entre sitios (XSS) mediante la Biblioteca de protección web de Microsoft .Net para obtener más información.
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.");
}
}
}
}