web-dev-qa-db-fra.com

Empêcher CSRF avec l'attribut de cookie du même site

Je surfais sur le Web et j'ai trouvé l'article Empêcher CSRF avec l'attribut de cookie du même site .

Comme sur le lien, nous devons ajouter un en-tête Set-Cookie.

Set-Cookie: clé = valeur; HttpOnly; SameSite = strict

Maintenant, ma question est, je veux définir cela dans mon site ASP.NET dans tous les cookies et cookies d'authentification. J'ai essayé de définir cela en utilisant l'en-tête de IIS mais quelqu'un dit que c'est une mauvaise implémentation.

J'ai également essayé ci-dessous.

HttpCookie newAuthenticationCookie = new HttpCookie(FormsAuthentication.FormsCookieName
                    , FormsAuthentication.Encrypt(newAuthenticationTicket))
                {
                    HttpOnly = true
                };
newAuthenticationCookie.Values.Add("SameSite", "strict");

Mais il semble que cela ne m'aide pas.

Veuillez me suggérer une meilleure façon de procéder.

Merci.

38
imlim

Après un examen approfondi sur Source HttpCookie il est confirmé que nous ne pouvons pas le faire avec le code, car il n'y a aucun moyen d'ajouter un attribut supplémentaire sur Cookie et la classe est marquée comme scellée.

Mais de toute façon, je gère la solution en modifiant web.config comme ci-dessous.

<rewrite>
  <outboundRules>
    <rule name="Add SameSite" preCondition="No SameSite">
      <match serverVariable="RESPONSE_Set_Cookie" pattern=".*" negate="false" />
      <action type="Rewrite" value="{R:0}; SameSite=strict" />
      <conditions>
      </conditions>
    </rule>
    <preConditions>
      <preCondition name="No SameSite">
        <add input="{RESPONSE_Set_Cookie}" pattern="." />
        <add input="{RESPONSE_Set_Cookie}" pattern="; SameSite=strict" negate="true" />
      </preCondition>
    </preConditions>
  </outboundRules>
</rewrite>

Cet ajout SameSite = strict sur chaque Set-Cookie .

45
imlim

Vous pouvez également définir cela dans le code lors de la création d'un cookie:

var httpCookie = new HttpCookie("mycookie", "myvalue");
httpCookie.Path += ";SameSite=Strict";

Response.SetCookie(httpCookie);

Cela vous donnera l'en-tête suivant:

Set-Cookie:mycookie=myvalue; path=/;SameSite=Strict

un peu de hack jusqu'à ce qu'il soit poussé dans le cadre.

21
Kevin Smith

Ajouter juste ma réponse pour systématiser toutes les informations trouvées ici et ailleurs.

1. Pour sécuriser les cookies personnalisés sous 4.7.2 et versions ultérieures

var c = new HttpCookie("test");
c.SameSite = SameSiteMode.Lax;

2. Pour sécuriser le cookie d'authentification Forms

Dans web.config

<authentication mode="Forms">
    <forms ..... cookieSameSite="Lax" />
</authentication>

3. Pour sécuriser le cookie de session ASP.NET

Dans Global.asax

void Session_Start(Object sender, EventArgs e)
{
    Response.Cookies["ASP.NET_SessionId"].SameSite = SameSiteMode.Lax;
    //while we're at it lets also make it secure
    if (Request.IsSecureConnection)
        Response.Cookies["ASP.NET_SessionId"].Secure = true;
}

Fait amusant: même si vous définissez <httpCookies requireSSL="true" /> le cookie de session ASP.NET sera toujours non sécurisé pour une raison quelconque.

MISE À JOUR 01.2020: Le cookie de session .NET 4.8 est désormais "SameSite" par défaut

L'installation de la dernière mise à jour de Windows rendra vos cookies de session Lax par dafault

4. <httpCookies samesite=xxx> n'existe pas

Ajouter <httpCookies sameSite="Strict" /> comme suggéré dans le commentaire ci-dessus dans web.config ne fonctionnait pas, j'obtenais l'erreur.

Attribut non reconnu 'samesite'

Même si je cible 4.7.2. Testé sur plusieurs projets et plusieurs machines, VS2019 ne le montre pas non plus dans intellisense et les documents MS ne le mentionnent nulle part.

19
Alex

.NET 4.7.2 prend désormais en charge la propriété SameSite.
Le HttpCookie a maintenant une propriété appelée SameSite.
Voir plus d'informations ici de Microsoft.

Plus besoin de pirater cela via le fichier de configuration.

14
tif

Pour que SameSite soit défini sur le cookie ASP.NET_SessionId, j'ai dû définir le fichier web.config dans la section system.web:

<sessionState cookieSameSite="Lax" />
10
Andre RB

Parce que de nos jours, nous utilisons owin pour corriger le même bug idiot de cookie webapi ...

public class CookieSameSiteMiddleware : OwinMiddleware
{
    public CookieSameSiteMiddleware(OwinMiddleware next) : base(next)
    {
    }

    public override async Task Invoke(IOwinContext context)
    {
        var url = context.Request.Path.Value.ToLowerInvariant();

        if (url.Contains("/api/mylogin"))
        {
            context.Response.OnSendingHeaders(x =>
            {
                var scv = context.Response.Headers.FirstOrDefault(h => h.Key == "Set-Cookie");
                if (!scv.Equals(default(KeyValuePair<string, string[]>)))
                {
                    //context.Response.Headers.Remove("Set-Cookie");
                    context.Response.Headers.Set("Set-Cookie", scv.Value[0] + "; SameSite=strict");
                }

            }, null);
        }

        await this.Next.Invoke(context);
    }
}

Assurez-vous que le middleware est enregistré avant .UseWebApi ()

8
maxfridbe

Avant 4.7.2, vous pouvez simplement ajouter la chaîne au chemin du cookie.

FormsAuthentication.SetAuthCookie(username, false, FormsAuthentication.FormsCookiePath + "; SameSite=Lax");
4
Jacob

https://www.nuget.org/packages/Microsoft.Owin.Security.Cookies/4.1. prend désormais en charge SameSite.

C'est une très bonne nouvelle car les autres solutions ici ne fonctionnent pas aussi bien:

Implémentation de OwinMiddleware: Fonctionne très bien, sauf pour les performances. Cela pourrait être quelque chose de spécifique pour notre environnement, mais cette solution représentait environ 10% de notre processeur.

<outboundRules>: Probablement possible de travailler. Mais toutes les solutions que j'ai vues jusqu'à présent et que nous avons testées, y compris celle de ce fil, ont rencontré des problèmes lorsque plusieurs cookies étaient définis dans la même réponse.

0
Mikael Eliasson