Estou tentando mitigar nossa vulnerabilidade ao ataque Poodle SSL 3.0 Fallback . Nossos administradores já começaram a desabilitar o SSL em favor do TLS para conexões de entrada para nossos servidores. E também aconselhamos nossa equipe a desabilitar o SSL em seus navegadores. Agora estou olhando nossa base de código .NET, que inicia conexões HTTPS com vários serviços por meio de System.Net.HttpWebRequest . Acredito que essas conexões podem ser vulneráveis a um ataque MITM se permitirem o fallback de TLS para SSL. Aqui está o que eu determinei até agora. Alguém poderia verificar novamente para verificar se estou certo? Esta vulnerabilidade é nova, então ainda não vi nenhuma orientação da Microsoft sobre como mitigá-la no .NET:
Os protocolos permitidos para a classe System.Net.Security.SslStream, que sustentam a comunicação segura em .NET, são definidos globalmente para cada AppDomain por meio da propriedade System.Net.ServicePointManager.SecurityProtocol .
O valor padrão dessa propriedade no .NET 4.5 é
Ssl3 | Tls
(embora eu não consiga encontrar documentação para fazer backup disso). SecurityProtocolType é um enum com o atributo Flags, portanto, é um OR bit a bit desses dois valores. Você pode verificar isso em seu ambiente com esta linha de código:Console.WriteLine (System.Net.ServicePointManager.SecurityProtocol.ToString ());
Isso deve ser alterado para apenas
Tls
, ou talvezTls12
, antes de iniciar qualquer conexão em seu aplicativo:System.Net.ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Tls;
Importante: como a propriedade oferece suporte a vários sinalizadores bit a bit, presumo que o SslStream não fará fallback automaticamente para outros protocolos não especificados durante o handshake. Caso contrário, qual seria o ponto de apoiar vários sinalizadores?
Atualização em TLS 1.0 vs 1.1 / 1.2:
De acordo com o especialista em segurança do Google Adam Langley, o TLS 1.0 foi posteriormente considerado vulnerável ao POODLE se não for implementado corretamente , então você deve considerar mudar para o TLS 1.2 exclusivamente.
Atualização para .NET Framework 4.7 e superior:
Conforme aludido pelo Prof Von Lemongargle abaixo, a partir da versão 4.7 do .NET Framework, não há necessidade de usar este hack, pois a configuração padrão permitirá que o SO escolha a versão do protocolo TLS mais segura. Consulte as práticas recomendadas de TLS (Transport Layer Security) com o .NET Framework para obter mais informações.
Respostas:
Estamos fazendo a mesma coisa. Para suportar apenas TLS 1.2 e nenhum protocolo SSL, você pode fazer o seguinte:
SecurityProtocolType.Tls é apenas TLS 1.0, nem todas as versões TLS.
Como um lado: se você quiser verificar se seu site não permite conexões SSL, você pode fazer isso aqui (não acho que isso será afetado pela configuração acima, tivemos que editar o registro para forçar o IIS a usar TLS para conexões de entrada): https://www.ssllabs.com/ssltest/index.html
Para desativar SSL 2.0 e 3.0 no IIS, consulte esta página: https://www.sslshopper.com/article-how-to-disable-ssl-2.0-in-iis-7.html
fonte
SecurityProtocolType.Tls11
eSecurityProtocolType.Tls12
valores enum só estão disponíveis em ASP.net 4.5 e para cima. Não tenho certeza do que teríamos que fazer para bases de código mais antigas rodando em 2.0 se o TLS 1.0 fosse deixado de lado.A resposta de @Eddie Loeffen parece ser a resposta mais popular para essa pergunta, mas tem alguns efeitos negativos a longo prazo. Se você revisar a página de documentação de System.Net.ServicePointManager.SecurityProtocol aqui, a seção de comentários implica que a fase de negociação deve apenas abordar isso (e forçar o protocolo é uma prática ruim porque, no futuro, o TLS 1.2 também será comprometido). No entanto, não estaríamos procurando por essa resposta se existisse.
Pesquisando, parece que o protocolo de negociação ALPN é necessário para chegar ao TLS1.2 na fase de negociação. Tomamos isso como nosso ponto de partida e testamos versões mais recentes do framework .Net para ver onde o suporte começa. Descobrimos que .Net 4.5.2 não oferece suporte à negociação para TLS 1.2, mas .Net 4.6 sim.
Portanto, embora forçar o TLS1.2 fará o trabalho agora, recomendo que você atualize para o .Net 4.6. Como este é um problema do PCI DSS de junho de 2016, a janela é curta, mas a nova estrutura é uma resposta melhor.
ATUALIZAÇÃO: Trabalhando a partir dos comentários, eu construí isto:
Para validar o conceito, juntei SSL3 e TLS1.2 e executei o código visando um servidor que suporta apenas TLS 1.0 e TLS 1.2 (1.1 está desabilitado). Com os protocolos OR, parece se conectar bem. Se eu mudar para SSL3 e TLS 1.1, houve falha na conexão. Minha validação usa HttpWebRequest de System.Net e apenas chama GetResponse (). Por exemplo, eu tentei isso e falhei:
enquanto isso funcionava:
Isso tem a vantagem de forçar o TLS 1.2, pois, se a estrutura .Net for atualizada para que haja mais entradas no Enum, elas serão suportadas pelo código no estado em que se encontram. Ele tem uma desvantagem em relação ao uso de .Net 4.6, pois o 4.6 usa ALPN e deve oferecer suporte a novos protocolos se nenhuma restrição for especificada.
Editar 29/04/2019 - A Microsoft publicou este artigo em outubro passado. Ele tem uma boa sinopse de sua recomendação de como isso deve ser feito nas várias versões do framework .net.
fonte
@watson
No windows forms está disponível, no topo da classe coloque
uma vez que o windows é single threaded, é tudo que você precisa; no caso de ser um serviço, você precisa colocá-lo logo acima da chamada para o serviço (já que não há como dizer em qual thread você estará).
também é necessário.
fonte
Se você estiver curioso para saber quais protocolos .NET são compatíveis, experimente o HttpClient em https://www.howsmyssl.com/
O resultado é terrível:
Como Eddie explica acima, você pode habilitar protocolos melhores manualmente:
Não sei por que ele usa protocolos ruins prontos para uso. Essa parece uma escolha de configuração ruim, equivalente a um grande bug de segurança (aposto que muitos aplicativos não mudam o padrão). Como podemos relatar isso?
fonte
Tive que lançar o equivalente inteiro para contornar o fato de que ainda estou usando o .NET 4.0
fonte
Descobri que a solução mais simples é adicionar duas entradas de registro da seguinte maneira (execute isso em um prompt de comando com privilégios de administrador):
Essas entradas parecem afetar a forma como o .NET CLR escolhe um protocolo ao fazer uma conexão segura como um cliente.
Há mais informações sobre essa entrada do registro aqui:
https://docs.microsoft.com/en-us/security-updates/SecurityAdvisories/2015/2960358#suggested-actions
Isso não apenas é mais simples, mas presumindo que funcione para o seu caso, é muito mais robusto do que uma solução baseada em código, que requer que os desenvolvedores rastreiem o protocolo e o desenvolvimento e atualizem todos os seus códigos relevantes. Felizmente, mudanças semelhantes no ambiente podem ser feitas para o TLS 1.3 e além, desde que o .NET permaneça burro o suficiente para não escolher automaticamente o protocolo mais alto disponível.
NOTA : Mesmo que, de acordo com o artigo acima, isso só desabilite o RC4, e ninguém pensaria que isso mudaria se o cliente .NET pode usar TLS1.2 + ou não, por algum motivo ele tem isso efeito.
NOTA : Como observado por @Jordan Rieger nos comentários, esta não é uma solução para o POODLE, uma vez que não desabilita os protocolos mais antigos a - apenas permite que o cliente trabalhe com os protocolos mais novos, por exemplo, quando um servidor com patch desabilitou os mais antigos protocolos. No entanto, com um ataque MITM, obviamente um servidor comprometido oferecerá ao cliente um protocolo mais antigo, que o cliente usará com prazer.
TODO : tente desativar o uso do lado do cliente de TLS1.0 e TLS1.1 com essas entradas de registro, mas não sei se as bibliotecas de cliente HTTP do .NET respeitam essas configurações ou não:
https://docs.microsoft.com/en-us/windows-server/security/tls/tls-registry-settings#tls-10
https://docs.microsoft.com/en-us/windows-server/security/tls/tls-registry-settings#tls-11
fonte