Você deveria usar cabeçalhos HTTP Strict Transport Security (HSTS) no seu servidor Node.js
Raphael Mun
29 de dezembro de 2022
0 minutos de leituraPara a maioria dos sites e aplicativos, o uso de cabeçalhos HTTP relacionados à segurança já se tornou uma prática padrão. Os sites usam cabeçalhos em solicitações e respostas HTTP para transmitir informações sobre uma página ou dados enviados pelo protocolo HTTP. Eles podem incluir um cabeçalho Content-Encoding para indicar que o conteúdo é um arquivo zip compactado ou um cabeçalho Location para especificar um URL de redirecionamento.
Entre os muitos cabeçalhos de segurança disponíveis que os navegadores modernos usam para proteger as pessoas, um tipo fundamental é o cabeçalho HTTP Strict Transport Security (HSTS). O cabeçalho HSTS fornecido por um site instrui o navegador a usar o protocolo HTTPS em todas as visitas seguintes.
No entanto, apesar da utilidade, da facilidade de implementação e do suporte de praticamente todos os navegadores, apenas cerca de 25% das respostas HTTP em dispositivos móveis e 28% em computadores incluem cabeçalhos HSTS.
Vamos conhecer a fundo os cabeçalhos HSTS para descobrir como afetam a segurança na web e por que devemos usá-los no Node.js. Em seguida, vamos aprender a ativar o HSTS em um servidor Node.js.
Por que ativar o HSTS?
As conexões HTTPS são seguras porque criptografam e descriptografam os pacotes de dados transmitidos usando certificados SSL/TLS, que podem ser verificados por autoridades certificadoras (CAs) conhecidas. Assim, somente o computador da pessoa usuária e o servidor conseguem ler os pacotes de dados transmitidos, independentemente de quem intercepte o tráfego da rede.
As conexões HTTP comuns não são criptografadas, o que significa que qualquer pessoa com acesso aos dados pode lê-los. Entre esses destinatários não autorizados podem estar servidores que roteiam e encaminham os dados da pessoa usuária até o servidor de destino ou alguém mal-intencionado que acessa o tráfego da rede em um roteador Wi-Fi público.
Confira estas descobertas do relatório Web Almanac 2022, que também contou com a coautoria da Snyk.

Atualmente, apenas 34% das respostas a solicitações em dispositivos móveis e 37% em computadores incluem a diretiva includeSubdomain.
A maioria restante fica mais suscetível a ataques de intermediário (MITM), que podem resultar em diversos problemas, desde roubo de dados de cartão de crédito ou de identidade até o comprometimento das credenciais de acesso ao nosso aplicativo web Node.js. Vale destacar que pessoas mal-intencionadas não precisam interceptar os dados no momento em que inserimos nossas credenciais de login. Os cookies do navegador costumam armazenar e enviar nossos tokens de sessão/acesso, permitindo que essas pessoas os obtenham por meio do sequestro de sessão.
Como o HSTS funciona?
Quando o cabeçalho HSTS está presente na resposta HTTP, os navegadores sabem que devem sempre usar uma conexão HTTPS com o servidor e redirecionam automaticamente as pessoas que se conectaram primeiro por HTTP. A partir daí, as conexões com o aplicativo ou site permanecem criptografadas e seguras, permitindo que o aplicativo use cookies seguros e ajudando a prevenir ataques de segurança MITM.
O cabeçalho HSTS tem três parâmetros diferentes. Vamos conhecê-los.
max - age = <expire-time>
Esse parâmetro obrigatório especifica por quantos segundos o navegador deve se lembrar de se conectar ao site por HTTPS. Quando esse período termina, o navegador carrega o site normalmente na próxima visita. O prazo é atualizado no navegador da pessoa usuária sempre que ele detecta o cabeçalho HSTS. Com isso, o parâmetro pode permanecer ativo indefinidamente. Como alternativa, alguns sites podem desativar o HSTS imediatamente definindo esse valor como 0.
Ao testar sua configuração de HSTS, você pode definir um período curto, como 300 segundos (cinco minutos). Depois de confirmar que o site funciona corretamente, você pode aumentar o período, por exemplo, para 31.536.000 segundos (um ano).
includeSubDomains
O parâmetro includeSubDomains é uma opção que instrui o navegador a ativar o HSTS no site e em todos os seus subdomínios. Como essa configuração se aplica de forma abrangente, antes de implementá-la, verifique se todos os seus subdomínios são compatíveis com HTTPS.
preload
Uma conexão inicial pode, potencialmente, usar uma conexão HTTP comprometida. Para lidar com isso, o Google mantém o parâmetro não oficial preload. A maioria dos principais navegadores oferece suporte a esse recurso de segurança, que reduz significativamente o risco. Um site pode adicionar o parâmetro preload ao cabeçalho HSTS e, em seguida, registrar o domínio no serviço de pré-carregamento. Assim, os navegadores podem consultar essa lista de referência para determinar se as conexões iniciais podem usar HTTPS. Para que o parâmetro preload funcione, é necessário definir o parâmetro max-age como pelo menos 31.536.000 segundos e ativar o parâmetro includeSubDomains.
Atenção: depois que o serviço de pré-carregamento adiciona seu domínio, uma solicitação de remoção pode levar vários meses para ser processada. Se quiser registrar seu domínio para pré-carregamento, consulte os requisitos de envio e as recomendações de implantação.
Reforce a segurança com HSTS
Vamos ver um exemplo de código para um servidor Node.js que responde com um cabeçalho HSTS. Todos os exemplos de código deste artigo são públicos e estão disponíveis no repositório de código aberto no GitHub.
Pré-requisitos
Para executar este projeto, você precisará de:
Um nome de domínio registrado
Um servidor com Node.js e as portas de rede 80 e 433 disponíveis
Um registro DNS válido para o domínio, apontando para o servidor
Obtenha um certificado SSL/TLS
Antes de ativar o HTTPS, precisamos de um certificado e uma chave privada para o domínio. Se ainda não tiver um, você pode obtê-los pelo Let’s Encrypt seguindo estas etapas:
Primeiro, instale o certbot seguindo estas instruções. No menu suspenso Software, selecione other e, no menu System, escolha o sistema operacional do seu servidor. Em seguida, siga as instruções exibidas.

Depois, verifique se as portas 80 e 443 estão abertas no servidor e execute o comando a seguir, informando o domínio do servidor:
Talvez seja necessário adicionar sudo ao início do comando e executá-lo como usuário privilegiado.

Agora, execute certbot certificates (com sudo, se necessário) para obter os caminhos dos arquivos do certificado e da chave privada.

Configure o código do servidor
Comece criando uma pasta para o projeto no servidor com o comando: mkdir snyk-demo.
Em seguida, acesse a pasta com: cd snyk-demo.
Depois, inicialize a pasta como um projeto Node.js usando: npm init -y.

Agora, vamos instalar algumas dependências do projeto para o servidor. Siga as instruções correspondentes ao Express ou ao Fastify.
Express:
Fastify:
Agora podemos criar um servidor Node.js básico com Express, usando HTTP e HTTPS.
Crie um arquivo index.js nesta pasta e adicione os seguintes módulos do Node no início do código.
Express:
Fastify:
Adicione o código a seguir para carregar os arquivos de certificado e substitua o valor de certificatePath pelo caminho do certificado do seu domínio. Se você usou o certbot do LetsEncrypt, execute certbot certificates para obter os caminhos dos arquivos.
Express:
Fastify:
Agora é hora de inicializar o aplicativo Express/Fastify e criar uma rota básica.
O código a seguir demonstra os três parâmetros HSTS, mas você pode começar usando apenas o parâmetro max-age.
Opção 1: use o middleware Helmet
A primeira forma de configurar o HSTS é usar o middleware Helmet durante a inicialização do aplicativo:
Express:
Fastify:
Opção 2: defina o cabeçalho manualmente
Outra opção é definir manualmente o cabeçalho HSTS por meio de um middleware que o aplique a todas as respostas:
Express:
Fastify:
Podemos finalizar o código criando os servidores HTTP e HTTPS com o código a seguir:
Express:
Fastify:
Para sua consulta, aqui estão os links para os repositórios com o código dos projetos Express e Fastify.
Por fim, execute o código do servidor com node index.js e abra seu domínio em um navegador.
Abra as ferramentas de desenvolvimento do navegador e inspecione os cabeçalhos da resposta na aba Network. Você verá que o cabeçalho HSTS está especificado.

E agora?
Agora que você aprendeu por que os cabeçalhos HTTP Strict Transport Security são importantes para a segurança de aplicativos Node.js, como ajudam a prevenir ataques MITM e como implementá-los no código Node.js, você já tem as ferramentas necessárias para proteger seus aplicativos web.
Há mais um ponto fundamental a lembrar. Em um ambiente de produção, não configure o HSTS nem sirva SSL pelo aplicativo Node.js. Em vez disso, delegue esses processos a servidores HTTP de arquivos estáticos, como NGINX ou Apache.



