Verificador de cabeçalhos HTTP de segurança
O que cada cabeçalho faz, o que o seu realmente diz e a linha que falta. Sem nota.
Por onde começar, se está a começar
Os cabeçalhos não valem todos o mesmo nem têm todos o mesmo risco de implantação. Por ordem daquilo que dá mais protecção com menor hipótese de partir alguma coisa:
| Cabeçalho | Impede | Risco de partir coisas |
|---|---|---|
Strict-Transport-Security | Desclassificação de HTTPS na primeira visita | Nenhum, se já servir apenas por HTTPS |
X-Content-Type-Options | Adivinhação de MIME em ficheiros carregados | Nenhum, na prática |
Referrer-Policy | Fuga de URL para terceiros | Baixo — pode afectar a atribuição nas estatísticas |
X-Frame-Options / frame-ancestors | Clickjacking | Baixo, a não ser que alguém o embeba legitimamente |
Permissions-Policy | Frames embebidos a pedir câmara ou localização | Baixo |
Content-Security-Policy | Execução de script injectado | Alto. Use primeiro o modo apenas de relatório. |
A última linha é a que mais importa e a única que dá trabalho a sério. Tudo o que está acima dela é uma tarde.
O HSTS, e a única decisão irreversível que traz
O Strict-Transport-Security diz ao navegador para usar HTTPS neste anfitrião durante os próximos max-age segundos, aconteça o que acontecer. Fecha uma brecha estreita mas real: quem escreve example.com faz um pedido em claro antes do seu redireccionamento, e esse pedido pode ser interceptado.
Strict-Transport-Security: max-age=31536000; includeSubDomainsO includeSubDomains conta mais do que parece. Sem ele, um subdomínio servido por HTTP ainda pode definir cookies para o domínio principal. Com ele, todos os subdomínios têm de ser só HTTPS ou ficam inacessíveis — portanto verifique antes de o acrescentar.
A directiva preload é a decisão a pensar com cuidado. Mete o seu domínio nas listas de pré-carregamento que os navegadores trazem consigo, portanto o HTTPS é imposto antes sequer do primeiro pedido. É também, na prática, irreversível: a remoção exige um pedido a quem mantém a lista e depois esperar que as versões dos navegadores se espalhem, o que são meses. Excelente quando tem a certeza; má ideia para acrescentar de ânimo leve.
CSP: o modo apenas de relatório não é opcional
Uma Content-Security-Policy é o único cabeçalho aqui que impede um script injectado de correr, e o único que lhe pode deitar o sítio abaixo. Ambos os factos decorrem da mesma propriedade: ela restringe o que pode ser carregado.
Ponha-a em produção em modo apenas de relatório, com um recolector, e deixe-a umas semanas com tráfego real. O que vai encontrar não é o que esperava da leitura do código — vai aparecer um servidor de tipos de letra esquecido, um iframe de pagamento e, muitas vezes, um script injectado na borda da CDN que não consta de ficheiro de origem nenhum. É precisamente essa última categoria que o modo de relatório existe para revelar.
Content-Security-Policy-Report-Only: default-src 'self';
script-src 'self'; object-src 'none'; base-uri 'self';
report-uri /csp-reportDuas coisas anulam a maior parte do benefício. O 'unsafe-inline' no script-src permite exactamente o script embutido injectado que a política existe para travar — a saída são nonces ou hashes. E o 'unsafe-eval' volta a ligar o eval e os seus parentes, de que algumas versões mais antigas de certas frameworks ainda precisam. O verificador assinala ambos como enfraquecimento e não como ausência, porque uma política com eles continua a fazer trabalho útil; apenas não faz o trabalho principal.
Cabeçalhos cujo conselho caducou
- `X-XSS-Protection` — controlava um filtro do navegador que foi removido de todos os navegadores importantes e que, no seu tempo, podia ele próprio ser manipulado para partir páginas. Não é um cabeçalho para definir em 2026.
- `Expect-CT` — obsoleto. A Certificate Transparency é agora imposta sem condições, portanto o cabeçalho não faz nada.
- `Feature-Policy` — passou a chamar-se
Permissions-Policy, com sintaxe diferente. Só o nome novo é respeitado. - `Public-Key-Pins` — removido dos navegadores, e ainda bem. Um erro nele inutilizava o seu domínio durante toda a vigência da fixação, sem forma de recuperar.
O que isto não verifica
Uma página, uma resposta. Lê os cabeçalhos da resposta final depois de seguir redireccionamentos, e pára aí. Não percorre o sítio, não avalia JavaScript, não testa a sua configuração de TLS nem verifica as bandeiras dos cookies — e caminhos diferentes do mesmo sítio podem enviar cabeçalhos completamente diferentes, portanto verificar a página inicial diz-lhe alguma coisa sobre a página inicial.
Para a configuração de TLS em concreto, o Qualys SSL Labs é a ferramenta consagrada e é minuciosa. Quanto ao certificado em si, esta lê o que um anfitrião apresenta de facto.
Perguntas sobre cabeçalhos
Porque é que não há pontuação nem nota?
Porque uma nota é justamente o resultado sobre o qual ninguém consegue agir. Saber que tem um C não lhe diz que cabeçalho falta, porque é que ele importa para o seu sítio, nem o que definir — e incentiva a acrescentar cabeçalhos para subir uma letra em vez de resolver um problema. Um sítio com uma CSP rigorosa e sem Permissions-Policy está em muito melhor forma do que um com seis cabeçalhos em valores permissivos, e nenhuma letra consegue exprimir isso. Por isso aqui reporta-se cada cabeçalho em separado, avalia-se o valor que realmente envia e dá-se-lhe a linha a acrescentar.
Que cabeçalho devo acrescentar primeiro?
Strict-Transport-Security, se já serve apenas por HTTPS. É uma linha, não pode partir nada que estivesse a funcionar e fecha a janela de desclassificação na primeira visita. Depois Content-Security-Policy em modo apenas de relatório — é essa que tem dentes a sério, e o modo de relatório deixa-o descobrir o que o seu sítio carrega de facto antes de impor seja o que for. O X-Content-Type-Options: nosniff também não custa nada e devia estar simplesmente ligado.
Uma Content-Security-Policy vai partir o meu sítio?
Pode, com toda a facilidade, e é para isso que existe o modo apenas de relatório. Ponha em produção o Content-Security-Policy-Report-Only com um recolector, deixe-o umas duas semanas com tráfego real e leia o que ele reporta — vai encontrar recursos de que já se tinha esquecido e, muitas vezes, coisas injectadas na borda por uma CDN ou por um fornecedor de estatísticas que não aparecem em ficheiro de origem nenhum. Só imponha quando os relatórios sossegarem. Impor uma política escrita a partir de uma leitura do código é a forma clássica de deitar abaixo a finalização da compra.
Vale a pena definir o X-XSS-Protection?
Não. Controlava um filtro de XSS do navegador que foi removido de todos os navegadores importantes — o Chrome abandonou-o em 2019 — e, no seu tempo, o próprio filtro introduzia vulnerabilidades, porque podia ser manipulado para partir páginas que não eram vulneráveis. Pô-lo a 0 é defensável se algum analisador insistir; pô-lo a 1; mode=block é repetir um conselho que caducou há anos. A substituição é a Content-Security-Policy.
Ainda preciso do X-Frame-Options se tiver CSP?
Não, desde que a sua CSP defina frame-ancestors, que o substitui em todos os navegadores actuais. Este verificador reconhece isso e não reporta o X-Frame-Options como em falta quando é o frame-ancestors que está a fazer o trabalho. Manter os dois não custa nada e só ajuda em navegadores tão antigos que provavelmente tem problemas maiores.
Um cabeçalho em falta quer dizer que estou vulnerável?
Não. Os cabeçalhos de segurança são defesa em profundidade — limitam o estrago de uma vulnerabilidade, não a criam nem a eliminam. Um sítio sem CSP não fica vulnerável a XSS; vulnerável fica um sítio com um defeito de XSS, e a CSP é o que impede esse defeito de se tornar um comprometimento total. Acrescentar cabeçalhos vale a pena e é barato, e não substitui a codificação da saída, a validação da entrada e a manutenção das dependências actualizadas.
Última revisão . Encontrou algo desactualizado? Diga-nos.
