Como lo indican las otras respuestas, el uso de controles de referencia por sí mismo no es suficiente y realmente debería usar tokens antifalsificación.
Sin embargo, como @jeffsix ha señalado, puede usar comprobaciones de referencia como una estrategia de defensa en profundidad (DID), por lo que un atacante tendría que derrotar múltiples defensas independientes para ejecutar un ataque exitoso.
El atributo ValidateReferrerAttribute a continuación se puede utilizar en sus acciones HttpPost MVC. Si el referente es nulo, no hace nada. Si el referente no es nulo, verifica que sea igual al nombre de host especificado. Solo tiene que agregarlo donde sea que esté utilizando ValidateAntiForgeryTokenAttribute, por lo que sería muy fácil de agregar.
/// <summary>
/// For POST requests, checks that the requests referrer is the current site. This could be used along side the ValidateAntiForgeryToken
/// Note that many clients do not send the referrer, so we do nothing in this case.
/// This attribute can be used as part of a Defence-in-Depth (DID) strategy, so an
/// attacker would need to defeat multiple, independent, defenses to execute a successful attack.
/// </summary>
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, Inherited = true, AllowMultiple = false)]
public class ValidateReferrerAttribute : FilterAttribute, IAuthorizationFilter
{
/// <summary>
/// Called when authorization is required.
/// </summary>
/// <param name="filterContext">The filter context.</param>
/// <exception cref="System.ArgumentNullException">filterContext</exception>
public void OnAuthorization(AuthorizationContext filterContext)
{
if (filterContext == null)
{
throw new ArgumentNullException("filterContext");
}
if ((filterContext.HttpContext.Request.UrlReferrer != null) &&
string.Equals(filterContext.HttpContext.Request.HttpMethod, "POST", StringComparison.OrdinalIgnoreCase) &&
!string.Equals(filterContext.HttpContext.Request.UrlReferrer.Host, filterContext.HttpContext.Request.Url.Host, StringComparison.OrdinalIgnoreCase))
{
this.HandleExternalPostRequest(filterContext);
}
}
/// <summary>
/// Handles post requests that are made from an external source.
/// By default a 403 Forbidden response is returned.
/// </summary>
/// <param name="filterContext">The filter context.</param>
/// <exception cref="System.Web.HttpException">Request not allowed.</exception>
protected virtual void HandleExternalPostRequest(AuthorizationContext filterContext)
{
throw new HttpException((int)HttpStatusCode.Forbidden, "Request not allowed.");
}
}
+1: Un enfoque interesante. –
pero es cierto que el enfoque de token antifalsificación eliminará la mayoría de los ataques basados en CSRF, pero no detendrá los bots que buscan registrar automáticamente (y luego enviar correo basura) a los usuarios de su sitio. Entonces, ¿cómo puedo estar 100% seguro de que mi sitio web está protegido? –
@johnG: Eso no es un ataque CSRF. Para detener spambots, lo que necesita es bueno [CAPTCHA] (http://en.wikipedia.org/wiki/CAPTCHA). (En realidad, [la seguridad a través de la oscuridad] (http://en.wikipedia.org/wiki/Security_through_obscurity) también puede funcionar bastante bien, al menos para sitios pequeños: si hace que su formulario de inicio de sesión sea lo suficientemente diferente de los demás, un nombre genérico bot no será capaz de entenderlo. Un spammer tendría que perder tiempo ajustando su bot solo para su sitio, lo que no es rentable para ellos a menos que su sitio sea realmente grande y popular.) –