Confundir intermediários maliciosos com a segurança de transporte HTTPS e HTTP Strict

Considerando a quantidade de dados pessoais que flui pela grande série de canais da Internet, a criptografia não é algo que podemos ou devemos ignorar. Os navegadores modernos oferecem vários mecanismos que podem ser usados para garantir a segurança dos dados dos usuários em trânsito: cookies seguros e Segurança de transporte estrita são dois dos mais importantes. Com elas, você protege perfeitamente os usuários, faz upgrade das conexões deles para HTTPS e garante que os dados deles nunca sejam enviados com clareza.

Por que isso é importante? Considere o seguinte:

Entregar uma página da Web por uma conexão HTTP não criptografada é mais ou menos o mesmo que entregar um envelope fechado à primeira pessoa que você encontrar na rua, que parece estar caminhando na direção dos correios. Se você tiver sorte, ela pode levar tudo até lá ou pode entregá-lo para a próxima pessoa que vê quem está indo no caminho certo. Essa pessoa pode fazer a mesma coisa e assim por diante.

A maioria dos estranhos nesta cadeia improvisada é confiável e nunca veria sua carta aberta ou a alteraria. No entanto, quanto mais vezes a letra mudar de mão, maior será o número de pessoas com acesso completo à carta que você está enviando. No fim, é bem provável que o destinatário pretendido da sua carta receba algo pelo e-mail, mas é uma pergunta aberta se esse é o mesmo algo que você entregou. Talvez você devesse ter fechado o envelope...

Intermediários

Para o bem ou para o mal, grandes trechos da Internet dependem da confiabilidade de pessoas desconhecidas. Os servidores não estão diretamente conectados entre si, mas transmitem solicitações e respostas de roteador para roteador em um enorme jogo de telefonia.

Use o traceroute para ver esses saltos em ação. A rota do meu computador para o HTML5Rocks é mais ou menos assim:

$ traceroute html5rocks.com
traceroute to html5rocks.com (173.194.71.102), 30 hops max, 60 byte packets
 1  router1-lon.linode.com (212.111.33.229)  0.453 ms
 2  212.111.33.233 (212.111.33.233)  1.067 ms
 3  217.20.44.194 (217.20.44.194)  0.704 ms
 4  google1.lonap.net (193.203.5.136)  0.804 ms
 5  209.85.255.76 (209.85.255.76)  0.925 ms
 6  209.85.253.94 (209.85.253.94)  1.226 ms
 7  209.85.240.28 (209.85.240.28)  48.714 ms
 8  216.239.47.12 (216.239.47.12)  22.575 ms
 9  209.85.241.193 (209.85.241.193)  36.033 ms
10  72.14.233.180 (72.14.233.180)  43.222 ms
11  72.14.233.170 (72.14.233.170)  43.242 ms
12  *
13  lb-in-f102.1e100.net (173.194.71.102)  44.523 ms

13 saltos não é ruim mesmo. No entanto, se eu estiver enviando solicitações por HTTP, cada um desses roteadores intermediários terá acesso total às minhas solicitações e às respostas dos servidores. Todos os dados estão sendo transferidos como texto simples não criptografado, e qualquer um desses intermediários pode atuar como um man-in-the-middle, lendo meus dados ou até mesmo manipulando-os em trânsito.

Para piorar, esse tipo de interceptação é praticamente indetectável. Uma resposta HTTP modificada de forma maliciosa é exatamente igual a uma resposta válida, já que não existe um mecanismo que permita garantir que os dados recebidos sejam _exatamente _ os dados enviados. Se alguém decidir ver minha Internet de cabeça para baixo para rir, eu tô sem sorte.

Esta linha é segura?

A mudança de HTTP de texto simples para uma conexão HTTPS segura oferece a melhor defesa contra intermediários. As conexões HTTPS criptografam todo o canal antes do envio de qualquer dado, o que impossibilita que as máquinas entre você e seu destino leiam ou modifiquem dados em trânsito.

A omnibox do Chrome oferece muitos detalhes sobre o status de uma conexão.
A omnibox do Chrome oferece muitos detalhes sobre o status de uma conexão.

A segurança do HTTPS está enraizada no conceito de chaves criptográficas públicas e privadas. Felizmente, uma discussão profunda dos detalhes está muito além do escopo deste artigo, mas a premissa principal é bastante direta: os dados criptografados com uma determinada chave pública podem ser descriptografados com a chave privada correspondente. Quando um navegador inicia um handshake de HTTPS para criar um canal seguro, o servidor fornece um certificado que fornece ao navegador todas as informações necessárias para verificar sua identidade, verificando se o servidor está de posse da chave privada adequada. Toda a comunicação daquele ponto em diante é criptografada de modo a provar que as solicitações foram entregues e as respostas recebidas do servidor autenticado.

Por isso, o HTTPS oferece alguma garantia de que você está se comunicando com o servidor e de que ninguém mais está detectando ou disfarçando bits na rede. Esse tipo de criptografia é um pré-requisito absoluto para a segurança na Web. Se o aplicativo não for fornecido por HTTPS no momento, ele estará vulnerável a ataques. Corrigir. O Ars Technica tem um ótimo guia para acessar e instalar um certificado sem custo financeiro. Recomendo que você confira os detalhes técnicos. A configuração varia de provedor para provedor e de servidor para servidor, mas o processo de solicitação de certificado é o mesmo em todos os lugares.

Segurança como padrão

Depois de solicitar e instalar um certificado, verifique se os usuários se beneficiam do seu trabalho: migre os usuários atuais para conexões HTTPS de maneira transparente usando o redirecionamento HTTP e garanta que os cookies sejam fornecidos apenas por conexões seguras.

Assim,

Quando um usuário acessar http://example.com/, redirecione-o para https://example.com/ enviando uma resposta 301 Moved Permanently com um cabeçalho Location apropriado:

$ curl -I http://mkw.st/
HTTP/1.1 301 Moved Permanently
Server: nginx/1.3.7
...
Keep-Alive: timeout=20
Location: https://mkw.st/

É possível configurar esse tipo de redirecionamento com facilidade em servidores como Apache ou Nginx. Por exemplo, uma configuração Nginx que redireciona de http://example.com/ para https://example.com/ é semelhante a esta:

server {
    listen [YOUR IP ADDRESS HERE]:80;
    server_name example.com www.example.com;
    location "/" {
        rewrite ^(.*) https://www.example.com$1 permanent;
    }
}

Os cookies permitem fornecer aos usuários experiências de login integradas usando o protocolo HTTP sem estado. Dados armazenados em cookies, incluindo informações confidenciais, como IDs de sessão, são enviados com cada solicitação, permitindo que o servidor entenda a qual usuário está respondendo no momento. Depois de garantir que os usuários acessem nosso site por HTTPS, também devemos garantir que os dados confidenciais armazenados em cookies sejam transferidos apenas por uma conexão segura e nunca sejam enviados claramente.

A definição de um cookie geralmente envolve um cabeçalho HTTP com esta aparência:

set-Cookie: KEY=VALUE; path=/; expires=Sat, 01-Jan-2022 00:00:00 GMT

Você pode instruir o navegador a restringir o uso do cookie a sessões seguras adicionando uma única palavra-chave:

Set-Cookie: KEY=VALUE; path=/; expires=Sat, 01-Jan-2022 00:00:00 GMT; secure

Os cookies definidos com a palavra-chave secure nunca serão enviados por HTTP.

Como fechar a janela aberta

O redirecionamento transparente para HTTPS significa que, na maioria dos casos, os usuários utilizam uma conexão segura. No entanto, isso deixa uma pequena janela de oportunidade para ataques: a conexão HTTP inicial está amplamente aberta, vulnerável a remoção de SSL e ataques relacionados. Como um usuário intermediário tem acesso total à solicitação HTTP inicial, ela pode atuar como um proxy entre você e o servidor, mantendo você em uma conexão HTTP sem segurança, independentemente das intenções do servidor.

Para reduzir o risco dessa classe de ataque, peça ao navegador para aplicar o HTTP Strict Transport Security (HSTS). O envio do cabeçalho HTTP Strict-Transport-Security instrui o navegador a fazer o redirecionamento HTTP para HTTPS no lado do cliente sem tocar na rede. Isso também é ótimo para o desempenho, porque a melhor solicitação é a que você não precisa fazer:

$ curl -I https://mkw.st/
HTTP/1.1 200 OK
Server: nginx/1.3.7
...
Strict-Transport-Security: max-age=2592000

Navegadores compatíveis com esse cabeçalho (atualmente Firefox, Chrome e Opera: caniuse tem detalhes) informam que esse site específico solicitou acesso somente HTTPS, ou seja, independentemente de como o usuário acessa o site, ele vai acessar por HTTPS. Mesmo que ela digite http://example.com/ no navegador, ela acabará usando HTTPS sem nunca fazer uma conexão HTTP. Melhor ainda, se o navegador detectar um certificado inválido (possivelmente tentando falsificar a identidade do servidor), os usuários não poderão continuar via HTTP. É tudo ou nada, o que é excelente.

O navegador vai expirar o status HSTS do servidor depois de max-age segundos (cerca de um mês neste exemplo). Defina esse valor como um valor razoavelmente alto.

Também é possível garantir que todos os subdomínios de uma origem estejam protegidos adicionando a diretiva includeSubDomains ao cabeçalho:

$ curl -I https://mkw.st/
HTTP/1.1 200 OK
Server: nginx/1.3.7
...
Strict-Transport-Security: max-age=2592000

Vá em frente, com segurança

HTTPS é a única maneira de ter certeza, mesmo remotamente, de que os dados enviados cheguem intactos ao destinatário pretendido. Configure conexões seguras para seus sites e aplicativos hoje mesmo. É um processo bastante simples e ajudará a manter os dados dos seus clientes seguros. Depois de implementar um canal criptografado, é necessário redirecionar os usuários de forma transparente para essa conexão segura, independentemente de como eles chegam ao seu site, enviando uma resposta HTTP 301. Em seguida, verifique se todas as informações confidenciais da sessão dos usuários usam apenas essa conexão segura adicionando a palavra-chave secure ao configurar os cookies. Depois de fazer tudo isso, garanta que seus usuários nunca caiam acidentalmente do ônibus: proteja-os garantindo que o navegador faça a coisa certa enviando um cabeçalho Strict-Transport-Security.

Configurar o HTTPS não é muito trabalhoso e traz grandes benefícios para o site e os usuários. Vale a pena o esforço.

Recursos

  • O StartSSL oferece certificados sem custo financeiro com domínio verificado. Você é insuperável. O avanço para níveis mais altos de verificação é, obviamente, possível e com preços razoáveis.
  • Teste de servidor SSL: depois de configurar o HTTPS nos seus servidores, verifique se você fez isso corretamente executando-o por meio do teste de servidor do SSL Labs. Você receberá um relatório bem detalhado que mostra se você está com tudo funcionando.
  • Vale a pena ler o artigo recente do Ars Technica, "Como proteger o servidor da Web com SSL/TLS (em inglês), para ver mais detalhes sobre os detalhes da configuração de um servidor.
  • Vale a pena dar uma olhada em todas as informações técnicas sobre o cabeçalho Strict-Transport-Security que podem ser do seu interesse na especificação HTTP Strict Transport Security (RFC6797).
  • Quando você realmente sabe o que está fazendo, uma próxima etapa possível seria anunciar que seu site só pode ser acessado por meio de um conjunto específico de certificados. Há alguns trabalhos em andamento no IETF que permitem que você faça isso pelo cabeçalho Public-Key-Pins. Ainda há alguns dias, mas é interessante e vale a pena acompanhar.