Confundir intermediários mal-intencionados com HTTPS e HTTP Strict Transport Security

Considerando a quantidade de dados pessoais que flui pela grande série de tubos que é a Internet, a criptografia não é algo que podemos ou devemos ignorar levianamente. Os navegadores mais recentes oferecem vários mecanismos que você pode usar para garantir que os dados dos usuários estejam seguros em trânsito: cookies seguros e Strict Transport Security são dois dos mais importantes. Eles permitem que você proteja seus usuários de forma integrada, fazendo upgrade das conexões para HTTPS e garantindo que os dados do usuário nunca sejam enviados sem criptografia.

Por que isso é importante para você? Considere o seguinte:

Exibir uma página da Web por uma conexão HTTP não criptografada é mais ou menos o mesmo que entregar um envelope aberto para a primeira pessoa que você vê na rua e que parece estar indo em direção ao correio. Se você tiver sorte, ela pode levar o pacote até o destino ou entregá-lo para a próxima pessoa que estiver indo na direção certa. Essa pessoa pode fazer o mesmo, e assim por diante.

A maioria dos estranhos nessa cadeia improvisada é confiável e nunca leria sua carta aberta nem a alteraria. No entanto, quanto mais vezes a carta mudar de mãos, maior será o número de pessoas com acesso completo à carta que você está enviando. No final, é bem provável que o destinatário da carta receba algo pelo correio, mas se esse algo é o mesmo que você entregou inicialmente é uma questão em aberto. Talvez você devesse ter selado aquele envelope…

Intermediários

Para o bem ou para o mal, grande parte da Internet depende da confiabilidade de estranhos. Os servidores não estão conectados diretamente uns aos outros, mas transmitem solicitações e respostas de roteador para roteador em um enorme jogo de telefone sem fio.

É possível ver esses saltos em ação com o traceroute. 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, na verdade. No entanto, se eu estiver enviando solicitações por HTTP, cada um desses roteadores intermediários terá acesso completo à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 agir como um Man in the Middle, lendo meus dados ou até mesmo os manipulando em trânsito.

Pior ainda, esse tipo de interceptação é praticamente indetectável. Uma resposta HTTP modificada de forma mal-intencionada é idêntica a uma resposta válida, já que não há um mecanismo que permita garantir que os dados recebidos são exatamente os mesmos que foram enviados. Se alguém decidir virar minha Internet de cabeça para baixo para dar risada, eu estarei mais ou menos sem sorte.

Esta linha é segura?

Mudar de HTTP de texto simples para uma conexão HTTPS segura é a melhor defesa contra intermediários. As conexões HTTPS criptografam todo o canal de ponta a ponta antes que qualquer dado seja enviado, impossibilitando que as máquinas entre você e seu destino leiam ou modifiquem dados em trânsito.

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

A segurança que o HTTPS oferece tem como base o conceito de chaves criptográficas públicas e privadas. Uma discussão profunda sobre os detalhes está (felizmente) muito além do escopo deste artigo, mas a premissa principal é bastante simples: os dados criptografados com uma determinada chave pública só podem ser descriptografados com a chave privada correspondente. Quando um navegador inicia um handshake HTTPS para criar um canal seguro, o servidor fornece um certificado que dá ao navegador todas as informações necessárias para verificar a identidade dele, confirmando que o servidor tem a chave privada adequada. Toda a comunicação a partir desse ponto é criptografada de modo a provar que as solicitações são entregues ao servidor de autenticação e as respostas são recebidas dele.

Portanto, o HTTPS garante que você está se comunicando com o servidor que acha que está e que ninguém mais está ouvindo ou alterando bits na transmissão. Esse tipo de criptografia é um pré-requisito absoluto para a segurança na Web. Se o aplicativo não for entregue por HTTPS, ele estará vulnerável a ataques. Corrigir. O Ars Technica tem um ótimo guia para obter e instalar um certificado (sem custo financeiro) que recomendo que você consulte para ver detalhes técnicos. A configuração varia de acordo com o provedor e o servidor, mas o processo de solicitação de certificado é o mesmo em todos os casos.

Segurança por padrão

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

Por aqui, por favor.

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 facilmente em servidores como Apache ou Nginx. Por exemplo, uma configuração do Nginx que redireciona de http://example.com/ para https://example.com/ é assim:

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

Os cookies nos permitem oferecer aos usuários experiências de login perfeitas no protocolo HTTP sem estado. Os dados armazenados em cookies, incluindo informações sensíveis, como IDs de sessão, são enviados com cada solicitação, permitindo que o servidor identifique o usuário que está recebendo a resposta no momento. Depois de garantir que os usuários acessem nosso site por HTTPS, também precisamos garantir que os dados confidenciais armazenados em cookies sejam transferidos apenas por uma conexão segura e nunca sejam enviados de forma não criptografada.

A configuração de um cookie geralmente envolve um cabeçalho HTTP semelhante a este:

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

É possível instruir o navegador a restringir o uso do cookie para proteger as sessões 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.

Fechando a janela aberta

O redirecionamento transparente para HTTPS significa que, na maior parte do tempo em que os usuários estiverem no seu site, eles usarão uma conexão segura. No entanto, ele deixa uma pequena janela de oportunidade para ataques: a conexão HTTP inicial fica totalmente aberta, vulnerável a SSL stripping e ataques relacionados. Como um intermediário tem acesso completo à solicitação HTTP inicial, ele pode atuar como um proxy entre você e o servidor, mantendo você em uma conexão HTTP não segura, independentemente das intenções do servidor.

Para reduzir o risco desse tipo 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 de HTTP para HTTPS no lado do cliente, sem tocar na rede. Isso também é ótimo para o desempenho, já que a melhor solicitação é aquela 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

Os navegadores que oferecem suporte a esse cabeçalho (atualmente, Firefox, Chrome e Opera: o caniuse tem detalhes) vão registrar que esse site específico solicitou acesso somente HTTPS, o que significa que, independentemente de como um usuário chega ao site, ele vai acessar por HTTPS. Mesmo que ela digite http://example.com/ no navegador, ela vai acabar no HTTPS sem nunca fazer uma conexão HTTP. Melhor ainda, se o navegador detectar um certificado inválido (potencialmente 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 após max-age segundos (cerca de um mês neste exemplo). Defina um valor razoavelmente alto.

Também é possível garantir que todos os subdomínios de uma origem sejam 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

Siga em frente com segurança

O HTTPS é a única maneira de ter certeza de que os dados enviados chegam intactos ao destinatário. Configure conexões seguras para seus sites e aplicativos hoje mesmo. É um processo bastante simples que ajuda a manter a segurança dos dados dos clientes. Depois de estabelecer um canal criptografado, redirecione 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 definir cookies. Depois de fazer tudo isso, garanta que os usuários nunca saiam 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 é difícil e traz grandes benefícios para seu site e os usuários. Vale muito a pena.

Recursos

  • A StartSSL oferece certificados sem custo financeiro validados por domínio. Não dá para competir com o que é sem custo financeiro. É possível passar para níveis mais altos de verificação por um preço razoável.
  • Teste de servidor SSL: depois de configurar o HTTPS para seus servidores, verifique se você fez isso corretamente executando o teste de servidor do SSL Labs. Você vai receber um relatório bem detalhado que mostra se você está realmente em funcionamento.
  • Vale a pena ler o artigo recente do Ars Technica "Securing your Web Server with SSL/TLS" para mais detalhes sobre os aspectos práticos da configuração de um servidor.
  • Vale a pena ler a especificação do HTTP Strict Transport Security (RFC6797) para conferir todas as informações técnicas sobre o cabeçalho Strict-Transport-Security que você possa querer.
  • Depois de entender bem o que está fazendo, uma próxima etapa possível seria anunciar que seu site só deve ser acessado por um conjunto específico de certificados. Há um trabalho em andamento na IETF que permitiria fazer exatamente isso usando o cabeçalho Public-Key-Pins. Ainda está no início, mas é interessante e vale a pena acompanhar.