Comment puis-je désactiver le retour en arrière SSL et utiliser uniquement TLS pour les connexions sortantes dans .NET? (Atténuation du caniche)

J’essaie d’atténuer notre vulnérabilité à l’attaque Poodle SSL 3.0 Fallback . Nos administrateurs ont déjà commencé à désactiver le protocole SSL en faveur de TLS pour les connexions entrantes vers nos serveurs. Et nous avons également conseillé à notre équipe de désactiver SSL dans leurs navigateurs Web. Je regarde maintenant notre base de code .NET, qui initie des connexions HTTPS avec divers services via System.Net.HttpWebRequest . Je crois que ces connexions pourraient être vulnérables à une attaque MITM si elles permettent un retour de TLS vers SSL. Voici ce que j’ai déterminé jusqu’ici. Quelqu’un pourrait-il le vérifier s’il vous plaît pour vérifier que j’ai raison? Cette vulnérabilité est nouvelle, je n’ai donc pas encore vu de conseils de Microsoft sur la manière de l’atténuer dans .NET:

  1. Les protocoles autorisés pour la classe System.Net.Security.SslStream, qui sous-tend la communication sécurisée dans .NET, sont définis globalement pour chaque AppDomain via la propriété System.Net.ServicePointManager.SecurityProtocol .

  2. La valeur par défaut de cette propriété dans .NET 4.5 est Ssl3 | Tls Ssl3 | Tls (bien que je ne puisse pas trouver de documentation pour le sauvegarder). SecurityProtocolType est un enum avec l’atsortingbut Flags, donc c’est un OU bit à bit de ces deux valeurs. Vous pouvez vérifier cela dans votre environnement avec cette ligne de code:

    Console.WriteLine (System.Net.ServicePointManager.SecurityProtocol.ToSsortingng ());

  3. Cela devrait être changé à seulement Tls , ou peut-être Tls12 , avant d’initier des connexions dans votre application:

    System.Net.ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Tls;

  4. Important: Étant donné que la propriété prend en charge plusieurs indicateurs au niveau du bit, je suppose que SslStream ne sera pas automatiquement remplacé par d’autres protocoles non spécifiés lors de la prise de contact. Sinon, quel serait l’intérêt de supporter plusieurs drapeaux?

Mise à jour sur TLS 1.0 vs 1.1 / 1.2:

Selon Adam Langley, expert en sécurité de Google, TLS 1.0 s’est révélé plus tard vulnérable à POODLE s’il n’était pas implémenté correctement . Vous devriez donc envisager de migrer exclusivement vers TLS 1.2.

Nous faisons la même chose. Pour prendre en charge uniquement TLS 1.2 et aucun protocole SSL, vous pouvez le faire:

 System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12; 

SecurityProtocolType.Tls est uniquement TLS 1.0, pas toutes les versions TLS.

Si vous souhaitez vérifier que votre site n’autorise pas les connexions SSL, vous pouvez le faire ici (je ne pense pas que cela sera affecté par le paramètre ci-dessus, nous avons dû modifier le registre pour forcer IIS à utiliser TLS). pour les connexions entrantes): https://www.ssllabs.com/ssltest/index.html

Pour désactiver SSL 2.0 et 3.0 dans IIS, consultez cette page: https://www.sslshopper.com/article-how-to-disable-ssl-2.0-in-iis-7.html

La réponse de @Eddie Loeffen semble être la réponse la plus populaire à cette question, mais elle a de mauvais effets à long terme. Si vous consultez la page de documentation de System.Net.ServicePointManager.SecurityProtocol , la section Remarques implique que la phase de négociation doit simplement y remédier (et forcer le protocole est une mauvaise pratique car à l’avenir, TLS 1.2 sera également compromis). Cependant, nous ne serions pas à la recherche de cette réponse si c’était le cas.

En recherchant, il apparaît que le protocole de négociation ALPN est nécessaire pour atteindre TLS1.2 dans la phase de négociation. Nous avons pris cela comme sharepoint départ et avons essayé de nouvelles versions du framework .Net pour voir où commencer le support. Nous avons constaté que .Net 4.5.2 ne prend pas en charge la négociation avec TLS 1.2, contrairement à .Net 4.6.

Donc, même si forcer TLS1.2 à faire le travail maintenant, je vous recommande plutôt de passer à .Net 4.6. Comme il s’agit d’une question de norme PCI DSS pour juin 2016, la fenêtre est courte, mais le nouveau cadre est une meilleure réponse.

MISE À JOUR: À partir des commentaires, j’ai construit ceci:

 ServicePointManager.SecurityProtocol = 0; foreach (SecurityProtocolType protocol in SecurityProtocolType.GetValues(typeof(SecurityProtocolType))) { switch (protocol) { case SecurityProtocolType.Ssl3: case SecurityProtocolType.Tls: case SecurityProtocolType.Tls11: break; default: ServicePointManager.SecurityProtocol |= protocol; break; } } 

Afin de valider le concept, j’ai assemblé SSL3 et TLS1.2 et exécuté le code ciblant un serveur qui ne supporte que TLS 1.0 et TLS 1.2 (la version 1.1 est désactivée). Avec les protocoles ou’d, il semble bien se connecter. Si je passe à SSL3 et TLS 1.1, la connexion a échoué. Ma validation utilise HttpWebRequest de System.Net et appelle simplement GetResponse (). Par exemple, j’ai essayé ceci et j’ai échoué:

  HttpWebRequest request = WebRequest.Create("https://www.contoso.com/my/web/resource") as HttpWebRequest; ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls11; request.GetResponse(); 

pendant que cela fonctionnait:

  HttpWebRequest request = WebRequest.Create("https://www.contoso.com/my/web/resource") as HttpWebRequest; ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls12; request.GetResponse(); 

Cela présente un avantage par rapport au forçage de TLS 1.2 dans la mesure où, si le framework .Net est mis à niveau pour qu’il y ait plus d’entrées dans Enum, elles seront sockets en charge par le code en l’état. Il est désavantagé par l’utilisation de .Net 4.6 dans la mesure où 4.6 utilise ALPN et devrait prendre en charge de nouveaux protocoles si aucune ressortingction n’est spécifiée.

@watson

Sur les formulaires Windows, il est disponible, en haut de la classe

  static void Main(ssortingng[] args) { ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12; //other stuff here } 

Windows étant à thread unique, c’est tout ce dont vous avez besoin, dans le cas où il s’agit d’un service, vous devez le placer juste au-dessus de l’appel au service (car vous ne savez pas sur quel thread).

 using System.Security.Principal 

est également nécessaire.

J’ai dû convertir l’équivalent entier pour contourner le fait que j’utilise toujours .NET 4.0

 System.Net.ServicePointManager.SecurityProtocol = (SecurityProtocolType)3072; /* Note the property type [System.Flags] public enum SecurityProtocolType { Ssl3 = 48, Tls = 192, Tls11 = 768, Tls12 = 3072, } */ 

Si vous êtes curieux de savoir quels protocoles sont supportés par .NET, vous pouvez essayer HttpClient sur https://www.howsmyssl.com/

 // set proxy if you need to // WebRequest.DefaultWebProxy = new WebProxy("http://localhost:3128"); File.WriteAllText("howsmyssl-httpclient.html", new HttpClient().GetSsortingngAsync("https://www.howsmyssl.com").Result); // alternative using WebClient for older framework versions // new WebClient().DownloadFile("https://www.howsmyssl.com/", "howsmyssl-webclient.html"); 

Le résultat est accablant:

Votre client utilise TLS 1.0, qui est très ancien, susceptible d’être attaqué par BEAST, et ne dispose pas des meilleures suites de chiffrement. Des ajouts comme AES-GCM et SHA256 pour remplacer MD5-SHA-1 ne sont pas disponibles pour un client TLS 1.0, ainsi que pour de nombreuses suites de chiffrement plus modernes.

Comme l’explique Eddie ci-dessus, vous pouvez activer manuellement de meilleurs protocoles:

 System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11; 

Je ne sais pas pourquoi il utilise de mauvais protocoles. Cela semble un mauvais choix de configuration, ce qui équivaut à un bug de sécurité majeur (je parie que beaucoup d’applications ne changent pas la valeur par défaut). Comment pouvons-nous le signaler?

J’ai trouvé la solution la plus simple consiste à append deux entrées de registre comme suit (exécutez ceci dans une invite de commande avec des privilèges d’administrateur):

 reg add HKLM\SOFTWARE\Microsoft\.NETFramework\v4.0.30319 /v SchUseStrongCrypto /t REG_DWORD /d 1 /reg:32 reg add HKLM\SOFTWARE\Microsoft\.NETFramework\v4.0.30319 /v SchUseStrongCrypto /t REG_DWORD /d 1 /reg:64 

Ces entrées semblent affecter la manière dont le CLR .NET choisit un protocole lorsqu’il établit une connexion sécurisée en tant que client.

Il y a plus d’informations sur cette entrée de registre ici:

https://docs.microsoft.com/en-us/security-updates/SecurityAdvisories/2015/2960358#suggested-actions

Non seulement c’est plus simple, mais en supposant que cela fonctionne pour votre cas, beaucoup plus robuste qu’une solution à base de code, ce qui oblige les développeurs à suivre le protocole et le développement et à mettre à jour tous leurs codes pertinents. Espérons que des modifications d’environnement similaires peuvent être apscopes à TLS 1.3 et au-delà, à condition que .NET rest suffisamment stupide pour ne pas choisir automatiquement le protocole disponible le plus élevé.

REMARQUE : Même si, selon l’article ci-dessus, cela est uniquement supposé désactiver RC4, on ne penserait pas que cela changerait si le client .NET est autorisé à utiliser TLS1.2 + ou non, pour une raison quelconque effet.

NOTE : Comme indiqué par @Jordan Rieger dans les commentaires, ce n’est pas une solution pour POODLE, car il ne désactive pas les anciens protocoles a – il permet simplement au client de travailler avec des protocoles plus récents, par exemple quand un serveur patché a désactivé l’ancien protocoles Cependant, avec une attaque MITM, il est évident qu’un serveur compromis offrira au client un ancien protocole, que le client utilisera alors avec plaisir.

TODO : Essayez de désactiver l’utilisation côté client de TLS1.0 et TLS1.1 avec ces entrées de registre, mais je ne sais pas si les bibliothèques client .NET http respectent ces parameters ou non:

https://docs.microsoft.com/fr-fr/windows-server/security/tls/tls-registry-settings#tls-10

https://docs.microsoft.com/en-us/windows-server/security/tls/tls-registry-settings#tls-11