10
votes

Devrais-je utiliser la validation de référence HTTP ou la vérification de jeton pour empêcher les attaques de la CSRF?

J'ai lu sur la manière de protéger mon site Web d'attaques CSRF dans une application Web ASP.NET MVC. Ils ont mentionné deux façons de le faire, soit par:

  1. Utilisation de la vérification de jeton en utilisant code> et [validateantanttiforgerytoken] code> p> p> p> p> l> p> p> p> p> p> p> p> p> p> p> LI>

  2. Utilisation de la validation de référence HTTP, telle que: P>

    [IsPostedFromThisSite]
    public ActionResult Register(…)
    


0 commentaires

4 Réponses :


2
votes

Le référateur HTTP (SIC) Header n'est pas fiable . Vous ne devriez pas en dépendre de cela pour quelque chose d'important. Pour quote Article CSRF de Wikipedia :

"Vérification du référateur HTTP en-tête pour voir si la demande provenait d'une page autorisée est couramment utilisée pour les périphériques réseau intégrés, car il n'augmente pas les exigences de la mémoire. Toutefois une demande qui omet le Référoir L'en-tête doit être traité comme non autorisé, car un attaquant peut supprimer le référateur en émettant des demandes d'URL de FTP ou HTTPS. Ce référateur Strict peut causer des problèmes avec les navigateurs ou mandataires qui omettent le Referer en-tête pour des raisons de confidentialité. en outre, les anciennes versions de flash (avant 9.0.18) permettent de flash malveillant de générer des requêtes GET ou POST avec les en-têtes de requête arbitraire HTTP par injection CRLF. Les vulnérabilités d'injection de CRLF similaires dans un client peuvent être utilisées pour spoof le référent d'une requête HTTP. "

Vérification du référent ne vous aidera pas non plus contre CSRF persistant < / a> Attaques, où l'attaquant parvient à injecter un lien malveillant directement sur votre site. Le seul moyen fiable de protéger contre de telles attaques est d'utiliser des jetons anti-falsification.


0 commentaires


10
votes

Vérification du référent est problématique. Tout d'abord, la spécification HTTP permet spécifiquement aux clients de ne pas envoyer de chaînes de référent (pour diverses raisons de confidentialité). Ainsi, certains de vos clients peuvent ne pas l'inclure. Deuxièmement, les chaînes de référencier peuvent être utilisées, où un attaquant de compétences suffisantes peut les faire ressembler à ce dont ils doivent être pour mener à bien une attaque de CSRF réussie.

L'utilisation d'un jeton de validation du CSRF est une approche plus forte et constitue la méthode privilégiée d'atténuation des attaques de la CSRF. Vous pouvez lire sur la raison pour laquelle cela se trouve sur le Feuille de triche Owasp CSRF .

Je soulignerai également qu'il n'y a aucune raison pour que vous ne puissiez pas faire les deux. Une stratégie de défense en profondeur (DID) est généralement souhaitable, de sorte qu'un attaquant devait vaincre plusieurs défenses de défense pour exécuter une attaque réussie. Vous pouvez implémenter une approche de vérification faiblement référendeuse (si un référent est fourni par le client, assurez-vous qu'il s'agit de ce qu'il devrait être avant d'agir sur la demande; si le référent n'est pas présent, procédez comme s'il était présent et correct) avec un jeton de validation du CSRF. De cette façon, vous vérifiez les informations référées si le client la fournit tout en utilisant toujours l'approche de jeton de validation plus forte.


3 commentaires

Mais est-il vrai que l'approche de jeton anti-falsification prendra la plupart des attaques CSRFBASED, mais elle n'arrêtera pas les bots qui recherchent des utilisateurs auto-enregistrez (puis spam) sur votre site. Donc, comment je peux sûr que je puisse sûr que mon site Web soit protégé.


@JOHNG: Ce n'est pas une attaque du CSRF. Pour arrêter les robots des robots, ce dont vous avez besoin est de bonne CAPTCHA . (En fait, Sécurité via obscurité peut trop bien fonctionner, au moins pour les petits sites: si vous Faites votre formulaire de connexion juste assez différent de tous les autres, un bot générique ne sera pas capable de le comprendre. Un spammeur devrait passer du temps à modifier son bot juste pour votre site, qui n'est pas rentable pour eux, à moins que votre site ne soit pas rentable. vraiment grand et populaire.)


@jeffsix J'aime l'idée de y compris un cochut de référateur "faible". C'est une couche supplémentaire décente.



4
votes

Comme indiqué par les autres réponses, l'utilisation de chèques de référents n'est pas suffisante et que vous devriez vraiment utiliser des jetons anti-falsification.

Toutefois, comme @jeffsix a souligné, vous pouvez utiliser des contrôles de référence comme une stratégie de défense en profondeur (DID). Un attaquant devrait donc vaincre plusieurs défenses de défense pour exécuter une attaque réussie. P >

L'attribut ValidAereFerrerRerattribute ci-dessous peut être utilisé sur vos actions HTTPPOST MVC. Si le référent est null, cela ne fait rien. Si le référent n'est pas nul, il vérifie qu'il est égal au nom d'hôte spécifié. Il vous suffit de l'ajouter où que vous utilisiez déjà le validateantantIforgeryTokenattribute, il serait donc très facile d'ajouter. P>

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


2 commentaires

Juste pour améliorer votre code légèrement (et faciliter la réutilisation), vous pouvez lire l'hôte actuel de filtercontext.httpcontext.request.url.host Signification que vous n'avez pas besoin d'avoir le "[host_name_here]" bit


Merci @matthewewetseaises. Mis à jour.