HSTS e cabeçalhos de segurança para o seu website
Em cada página, o seu servidor web envia cabeçalhos (headers): linhas curtas com instruções para o browser. Estes determinam, em parte, o nível de segurança com que o browser trata o seu site. Aqui pode ler o que é o HSTS, que outros cabeçalhos de segurança existem e como os configurar e testar.
Primeiro, o seu site tem de ter um certificado funcional e redirecionar os visitantes para https. Pode ler como fazê-lo em Ativar e renovar o certificado SSL e resolver problemas e Redirecionar obrigatoriamente os visitantes para https.
O que faz o HSTS?
O redirecionamento para https tem um ponto fraco: o primeiro pedido via http ainda é enviado sem encriptação. Alguém na mesma rede, por exemplo numa rede wifi pública, pode intercetar esse pedido. O HSTS (HTTP Strict Transport Security) resolve esse problema. O seu site envia, via https, este cabeçalho:
Strict-Transport-Security: max-age=31536000
O browser memoriza então que só pode abrir o seu site via https. Se mais tarde um visitante escrever http://, o próprio browser converte o endereço em https, antes de qualquer dado circular pela rede. O browser ignora um cabeçalho HSTS recebido através de http simples.
| Elemento | Significado |
|---|---|
max-age | Durante quanto tempo o browser memoriza a instrução, em segundos. O teste do internet.nl considera suficiente um período mínimo de um ano (31536000). |
includeSubDomains | Aplica-se também a todos os subdomínios, como shop.oseudominio.pt e mail.oseudominio.pt. |
preload | Pede a inclusão na lista integrada nos browsers (hstspreload.org). Assim, até a primeiríssima visita fica protegida. Para tal são necessários, entre outros, um ano, includeSubDomains e https em todos os subdomínios. Sair da lista demora muito tempo. |
max-age=0 | Apaga a instrução memorizada, na visita seguinte via https. |
includeSubDomains, o mesmo se aplica a cada subdomínio, como uma antiga página de câmara ou impressora sem certificado. Por isso, avance gradualmente: comece com um max-age curto, por exemplo um dia (86400), verifique se tudo funciona e aumente por etapas até um ano.HSTS na WebOké
Na maioria dos nossos servidores, o servidor web envia o HSTS por predefinição para cada website aberto via https: Strict-Transport-Security: max-age=31536000. Isto corresponde a um ano, sem includeSubDomains e sem preload. Não precisa de fazer nada para isso. Em alguns servidores não está ativo por predefinição; aí terá de o ativar. Pode verificar se o seu site já envia o HSTS, e com que max-age, nas ferramentas de programador do seu browser ou no teste do internet.nl (ver abaixo).
O interruptor de HSTS no DirectAdmin
No DirectAdmin, aceda a Domínios e clique no nome do seu domínio. Se SSL Seguro estiver ativo, verá junto ao HSTS o interruptor Ativar HTTP Strict Transport Security. Em seguida, clique em Editar para guardar. Pode ler como fazê-lo passo a passo em Redirecionar sempre os visitantes para https.
Se o seu site já envia o HSTS, não precisa do interruptor. Ative-o apenas se o seu site ainda não enviar o HSTS. Configure o HSTS num único local: no DirectAdmin ou no .htaccess, nunca em ambos. Se o browser receber dois cabeçalhos HSTS, utiliza apenas o primeiro.
Os outros cabeçalhos de segurança
| Cabeçalho | Protege contra | Valor para começar |
|---|---|---|
X-Content-Type-Options | O browser tenta adivinhar o tipo de um ficheiro, o que pode fazer com que uma "imagem" carregada seja executada como script. | nosniff (o único valor válido) |
Content-Security-Policy: frame-ancestors ou X-Frame-Options | Clickjacking: outro site carrega a sua página de forma invisível numa frame, para que os visitantes cliquem nos seus botões sem se aperceberem. | frame-ancestors 'self', ou o cabeçalho mais antigo X-Frame-Options: SAMEORIGIN |
Referrer-Policy | Ao clicar para outro site, o browser envia o endereço da página anterior, por vezes com um termo de pesquisa ou número de encomenda incluído. | strict-origin-when-cross-origin, ou, mais restritivo, same-origin ou no-referrer. O internet.nl só considera corretos os valores restritivos. |
Permissions-Policy | Determina que funcionalidades do browser a sua página e as frames incorporadas podem utilizar, como câmara, microfone e localização. | camera=(), microphone=(), geolocation=() desativa essas três. Se o seu site utilizar uma dessas funcionalidades, omita-a. |
Content-Security-Policy (completa) | Limita os locais de onde podem ser carregados scripts, estilos e imagens. Isto dificulta muito a inserção de scripts maliciosos (XSS). | Configuração personalizada para cada site. Evite unsafe-inline, unsafe-eval e wildcards. |
Configurar no .htaccess
Coloque estas linhas no início do ficheiro .htaccess na pasta public_html do seu domínio. Faça primeiro uma cópia do ficheiro.
<IfModule mod_headers.c> Header always set X-Content-Type-Options "nosniff" Header always set Content-Security-Policy "frame-ancestors 'self'" Header always set Referrer-Policy "strict-origin-when-cross-origin" Header always set Permissions-Policy "camera=(), microphone=(), geolocation=()" # Apenas se o seu site ainda não enviar o HSTS (ver acima): # Header always set Strict-Transport-Security "max-age=31536000" </IfModule>
Adicione includeSubDomains apenas quando tiver a certeza de que todos os subdomínios têm https. Se utilizar o WordPress, também pode configurar os cabeçalhos com um plugin. Escolha um plugin conhecido que ainda seja atualizado e configure cada cabeçalho num único local: no plugin ou no .htaccess.
Content-Security-Policy-Report-Only. Este não bloqueia nada, mas mostra na consola do browser o que seria bloqueado. Em caso de dúvida, deixe isto a cargo do seu programador web, ou comece apenas com frame-ancestors.Num VPS com nginx ou Caddy
Num VPS não utiliza o DirectAdmin e, muitas vezes, também não o .htaccess. Nesse caso, configura os cabeçalhos nas definições do seu servidor web. Nenhum dos dois envia o HSTS ou estes cabeçalhos automaticamente.
nginx: no bloco server para a porta 443:
add_header Strict-Transport-Security "max-age=31536000" always; add_header X-Content-Type-Options "nosniff" always; add_header Content-Security-Policy "frame-ancestors 'self'" always; add_header Referrer-Policy "strict-origin-when-cross-origin" always;
Com always, os cabeçalhos também são enviados nas páginas de erro. Atenção: se um bloco location tiver o seu próprio add_header, as regras do bloco server deixam de se aplicar a essa location. Nesse caso, repita-as aí ou coloque-as num ficheiro separado que insere em todo o lado com include. Teste as definições com nginx -t e carregue-as com systemctl reload nginx.
Caddy: no bloco do seu site no Caddyfile:
header {
Strict-Transport-Security "max-age=31536000"
X-Content-Type-Options "nosniff"
Content-Security-Policy "frame-ancestors 'self'"
Referrer-Policy "strict-origin-when-cross-origin"
}
Carregue a alteração com systemctl reload caddy. Para a configuração de um site com nginx ou Caddy, consulte nginx com um certificado da Let's Encrypt e Caddy: um website com https automático no manual do VPS.
Testar
- Internet.nl: introduza o seu domínio no teste de websites em internet.nl.
- O seu browser: abra o seu site, prima F12 (ou escolha Inspecionar), aceda ao separador Rede, recarregue a página e clique no primeiro pedido. Em Cabeçalhos de resposta (Response Headers) vê tudo o que o seu servidor envia.
- A linha de comandos:
curl -sI https://oseudominio.pt/mostra os cabeçalhos.
Após cada alteração, verifique se o seu site, os formulários e a página de pagamento continuam a funcionar. Mantenha também o seu CMS, plugins e temas atualizados. Consulte Proteger o wp-login.php do WordPress.
Leitura adicional
- MDN: Strict-Transport-Security (em inglês)
- MDN: Content-Security-Policy (em inglês)
- MDN: Permissions-Policy (em inglês)
- Lista de preload HSTS (em inglês)
Quer aprender mais? Frequente o curso gratuito Segurança online para empresários, lição 4.2 O seu website: https, HSTS e cabeçalhos de segurança, ou o curso gratuito de WordPress, lição 7.4 Reforçar o site: permissões, cabeçalhos e plugins de segurança.
